C
I loved locking up folders as a kid on the Windows 7 computers using batch scripts I didn't understand.
# Welcome to the bytelocker!
This is a small program written in C to help me consolidate by understanding of `FILE` streams, *bitwise operations* and *memory representations* of data.
## What does bytelocker do?
Bytelocker takes in 2 arguments, a file and a password. It then encrypts this file in place with an ECB cipher.
## Why is this useful?
Whilst you can use this binary from the command line to encrypt a standalone file, as is the case with many `C` programs, you will find this integrates nicely within larger workflows. See below.
### My usecase.
I spend my day in vim and vimwiki. And sometimes I need to document slightly sensitive information which I don't feel comfortable leaving in plaintext. As such, I have added a binding to my vimrc calling the bytelocker utility.
The code snippet looks like:
`nnoremap E :silent ! '/Users/aayushbajaj/Google Drive/2. - code/202. - c/202.6 - bytelocker/bytelocker' '%' '$bl_pass'<CR>:set noro<CR>`
here pressing capital E in normal mode will encrypt the file.
- `silent` suppresses output
- `!` is the execution of a shell command, which then runs the bytelocker executable from my google drive
- `%` is a vim macro for the current file
- and the password is retrieved from an environmental variable defined in `.zprofile`.
- the definition looks like `export bl_pass="passwordpassword"`
- **NOTE: the password must be 16 characters!!**
- **NOTE: if you choose to define the password in another file, make sure your viwrc sources the file**
- the line in .vimrc would look something like `so "~/.config/zsh/.zprofile"
### Demo
tl;dr this used to be a standalone repo.
Caesar
some of the code I've written is so stupid I tell you.
this one basically fires up a REPL with a argv[1] as the number of forward caesar cipher steps you want to take.
really not worth running.
#include <stdio.h>
#include <stdlib.h>
int upper(int character, int shift) {
character += shift;
if (character > 90) {
character = (character-90)%26 + 64;
}
else if (character < 65) {
character = (65-character)%26;
if (character == 0) return 65;
character = 91 - character;
}
return character;
}
int lower(int character, int shift) {
character += shift;
if (character > 122) {
character = (character-122)%26 + 96;
}
else if (character < 97) {
character = (97-character)%26;
if (character == 0) return 97;
character = 123 - character;
}
return character;
}
int main(int argc, char* argv[]) {
int shift = atoi(argv[1]);
int character = getchar();
while (character != EOF) {
if (character >= 'A' && character <= 'Z') {
putchar(upper(character, shift));
}
else if (character >= 'a' && character <= 'z') {
putchar(lower(character, shift));
}
else putchar(character);
character = getchar();
}
}File XOR
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *fi, *fo;
char *cp;
int c;
if ((cp = argv[1]) && *cp!='\0') {
if ((fi = fopen(argv[2], "rb")) != NULL) {
if ((fo = fopen(argv[3], "wb")) != NULL) {
while ((c = getc(fi)) != EOF) {
if (!*cp) cp = argv[1];
c ^= *(cp++);
putc(c,fo);
}
fclose(fo);
}
fclose(fi);
}
}
}Again, not my code, but it was on my drive. It shall be helpful for when I reimplement it in Java for my arcade.
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// Macro-defined constants:
#define N_COLS 15
#define N_ROWS 15
#define MAX_SNAKE_LEN (N_COLS * N_ROWS)
#define EMPTY 0
#define SNAKE_HEAD 1
#define SNAKE_BODY 2
#define APPLE 3
#define NORTH 0
#define EAST 1
#define SOUTH 2
#define WEST 3
// Prototypes --- major game operations:
void init_snake(void);
void update_apple(void);
bool update_snake(int direction);
bool move_snake_in_grid(int new_head_row, int new_head_col);
void move_snake_in_array(int new_head_row, int new_head_col);
// Prototypes --- utility functions:
void set_snake(int row, int col, int body_piece);
void set_snake_grid(int row, int col, int body_piece);
void set_snake_array(int row, int col, int nth_body_piece);
void print_grid(void);
int input_direction(void);
int get_d_row(int direction);
int get_d_col(int direction);
void seed_rng(unsigned int seed);
unsigned int rand_value(unsigned int n);
// Constants:
const char symbols[4] = {'.', '#', 'o', '@'};
// Globals:
int8_t grid[N_ROWS][N_COLS] = { EMPTY };
int8_t snake_body_row[MAX_SNAKE_LEN] = { EMPTY };
int8_t snake_body_col[MAX_SNAKE_LEN] = { EMPTY };
int snake_body_len = 0;
int snake_growth = 0;
int snake_tail = 0;
// Code:
// `main' (not provided):
// Run the main game loop!
int main(void) {
init_snake();
update_apple();
int direction;
do {
print_grid();
direction = input_direction();
} while (update_snake(direction));
int score = snake_body_len / 3;
printf("Game over! Your score was %d\n", score);
return 0;
}
// `init_snake' (not provided):
// Set the snake's initial location.
void init_snake(void) {
set_snake(7, 7, SNAKE_HEAD);
set_snake(7, 6, SNAKE_BODY);
set_snake(7, 5, SNAKE_BODY);
set_snake(7, 4, SNAKE_BODY);
}
// `update_apple' (not provided):
// Pick a random new location to place an apple.
void update_apple(void) {
int apple_row;
int apple_col;
do {
apple_row = rand_value(N_ROWS);
apple_col = rand_value(N_COLS);
} while (grid[apple_row][apple_col] != EMPTY);
grid[apple_row][apple_col] = APPLE;
}
// `update_snake' (not provided):
// Move the snake one step in `direction' by updating the snake
// locations on the grid and in the array. Handle consuming apples.
// Trigger a game-over if we wander off the edges of the board.
bool update_snake(int direction) {
int d_row = get_d_row(direction);
int d_col = get_d_col(direction);
int head_row = snake_body_row[0];
int head_col = snake_body_col[0];
grid[head_row][head_col] = SNAKE_BODY;
int new_head_row = head_row + d_row;
int new_head_col = head_col + d_col;
if (new_head_row < 0) return false;
if (new_head_row >= N_ROWS) return false;
if (new_head_col < 0) return false;
if (new_head_col >= N_COLS) return false;
// Check if there is an apple where the snake's head will be
// *before* we move the snake, and thus overwrite the apple.
bool apple = (grid[new_head_row][new_head_col] == APPLE);
snake_tail = snake_body_len - 1;
if (! move_snake_in_grid(new_head_row, new_head_col)) {
return false;
}
move_snake_in_array(new_head_row, new_head_col);
if (apple) {
snake_growth += 3;
update_apple();
}
return true;
}
// `move_snake_in_grid' (not provided):
// Paint the snake onto the grid, moving the head along by a step,
// and removing tail segments. Fail if this move would cause us
// to run into our own body.
bool move_snake_in_grid(int new_head_row, int new_head_col) {
if (snake_growth > 0) {
snake_tail++;
snake_body_len++;
snake_growth--;
} else {
int tail = snake_tail;
int tail_row = snake_body_row[tail];
int tail_col = snake_body_col[tail];
grid[tail_row][tail_col] = EMPTY;
}
if (grid[new_head_row][new_head_col] == SNAKE_BODY) {
return false;
}
grid[new_head_row][new_head_col] = SNAKE_HEAD;
return true;
}
// `move_snake_in_array':
// Update record of where the snake's body segments are, when the head
// is now in a new location.
void move_snake_in_array(int new_head_row, int new_head_col) {
for (int i = snake_tail; i >= 1; i--) {
set_snake_array(snake_body_row[i - 1], snake_body_col[i - 1], i);
}
set_snake_array(new_head_row, new_head_col, 0);
}
////////////////////////////////////////////////////////////////////////
///
/// The following functions are already implemented in assembly for you.
///
/// You may find it very useful to read through these functions in C and
/// in assembly, but you do not need to do so.
///
// `set_snake' (provided):
// Set up the snake by painting it onto the grid and by recording where
// that piece of the body was. Only really used in `init_snake'.
void set_snake (int row, int col, int body_piece)
{
set_snake_grid(row, col, body_piece);
set_snake_array(row, col, snake_body_len);
snake_body_len++;
}
// `set_snake_grid' (provided):
// Place `body_piece' into the grid at `row' and `col'.
void set_snake_grid(int row, int col, int body_piece) {
grid[row][col] = body_piece;
}
// `set_snake_array' (provided):
// Record that the nth piece of the snake's body is at `row' and `col'.
void set_snake_array(int row, int col, int nth_body_piece) {
snake_body_row[nth_body_piece] = row;
snake_body_col[nth_body_piece] = col;
}
// `print_grid' (provided):
// Draw the whole grid to the screen.
void print_grid(void) {
putchar('\n');
for (int i = 0; i < N_ROWS; i++) {
for (int j = 0; j < N_COLS; j++) {
char symbol = symbols[grid[i][j]];
putchar(symbol);
}
putchar('\n');
}
}
int last_direction = EAST;
// `input_direction' (provided):
// Read in the next direction that the user wants to move in.
// Handles invalid input by telling the user their input was bad.
// Handles inputs that the snake cannot move in by going bonk.
int input_direction(void) {
int direction;
do {
if ((direction = getchar()) == EOF) {
exit (0);
}
switch (direction) {
case 'w': direction = NORTH; break;
case 'a': direction = WEST; break;
case 's': direction = SOUTH; break;
case 'd': direction = EAST; break;
case '\n': continue;
case '\0':
case '\004':
exit(0);
default: {
printf("invalid direction: %c\n", direction);
continue;
}
}
if (
0 <= direction && direction <= 3 &&
abs(last_direction - direction) != 2
) {
last_direction = direction;
return direction;
}
printf("bonk! cannot turn around 180 degrees\n");
} while (true);
}
// `get_d_row' (provided):
// Determine the delta-row we want to move to.
int get_d_row(int direction) {
if (direction == SOUTH) {
return 1;
} else if (direction == NORTH) {
return -1;
} else {
return 0;
}
}
// `get_d_col' (provided):
// Determine the delta-column we want to move to.
int get_d_col(int direction) {
if (direction == EAST) {
return 1;
} else if (direction == WEST) {
return -1;
} else {
return 0;
}
}
///
/// A very simple pseudo-random number generator.
///
/// `rand_seed', `seed_rng', and `rand_value' implement a pseudo-random
/// number generator --- specifically, a linear congruential generator.
/// (You may like to read more about randomness and random numbers ---
/// it's very interesting!)
///
unsigned int rand_seed = 0;
// `seed_rng' (provided):
// Set the initial seed for our simple pseudo-random number generator.
// This is a bit like `srand(3)', but we can't use that on SPIM.
void seed_rng(unsigned int seed) {
rand_seed = seed;
}
// `rand_value' (provided):
// Get a random number between 0 and `n', and mix in some randomness.
// This is a bit like `rand(3)', but we can't use that on SPIM.
unsigned int rand_value(unsigned int n) {
rand_seed = (rand_seed * 1103515245 + 12345) & 0x7FFFFFFF;
return rand_seed % n;
}OCR
This was one of the first times I fell in love with Machine Learning, without knowing that the magic came from Machine Learning methods.
I simply had a `pdf` file with handwritten or scanned text, and desperately wanted to find something within the document without having to do it manually.
I google online for an OCR; upload my file; download it back again, and hey presto — such magical, accurate results!