#include #include #include /* * While no EOF * Encrypt block using key * Output ciphertext * Might have a partial block */ /* * Password Length: 64 bits, but specified in ASCII * Block size: 64 bits */ __uint128_t ipow(int n, int e){ __uint128_t retval = 1; for(int i = 0; i < e; i++) retval *= n; return retval; } size_t text_to_hex(char* password){ char hex_password[8]; __uint128_t pwd_so_far = 0; for(int i = 0; i < strlen(password); ++i){ pwd_so_far += (password[i] - 32) * ipow(94, i); } size_t final_password = (size_t)pwd_so_far; printf("Final password: %lx\n", final_password); return final_password; // If we do it like this, we'll return a pointer to the stack! } int main(int argc, char ** argv){ if(argc < 2){ printf("Usage: %s password [-d]\n", argv[0]); return 1; } char mode = 0; if(argc > 2 && argv[2][1] == 'd') mode = 1; // char pass_section[3]; // pass_section[2] = 0; unsigned char password[8]; *(size_t*)password = text_to_hex(argv[1]); unsigned result; /* for(int offset = 0; offset < 16; offset += 2){ pass_section[0] = argv[1][offset]; pass_section[1] = argv[1][offset+1]; sscanf(pass_section, "%x", &result); password[offset/2] = result; } // This was from the old days, when the user had to type hex characters! */ unsigned char plaintext[8]; unsigned char ciphertext[8]; size_t readlen; do { readlen = read(0, plaintext, 8); for(int byte = 0; byte < readlen; byte++){ if(!mode) ciphertext[byte] = plaintext[byte] + password[byte] % 256; else ciphertext[byte] = plaintext[byte] - password[byte] % 256; } write(1, ciphertext, readlen); } while (readlen == 8); return 0; }