26 printf(
" %s -e SHIFT \"text\" Caesar encrypt\n", prog);
27 printf(
" %s -d SHIFT \"text\" Caesar decrypt\n", prog);
28 printf(
" %s -c \"ciphertext\" Caesar crack (chi-squared)\n", prog);
29 printf(
" %s -v --key=KEY \"text\" Vigenère encrypt\n", prog);
30 printf(
" %s -V --key=KEY \"text\" Vigenère decrypt\n", prog);
31 printf(
" %s -x --key=KEY \"text\" XOR cipher (encrypt = decrypt)\n", prog);
32 printf(
" %s -s \"text\" SHA-256 hex digest\n", prog);
35static char *
join_args(
int argc,
char *argv[],
int start) {
36 if (start >= argc)
return NULL;
38 for (
int i = start; i < argc; i++) total += strlen(argv[i]) + 1;
39 char *buf = malloc(total + 1);
40 if (!buf)
return NULL;
42 for (
int i = start; i < argc; i++) {
43 if (i > start) strcat(buf,
" ");
49int main(
int argc,
char *argv[]) {
56 NONE, CAESAR_ENC, CAESAR_DEC, CAESAR_CRACK,
57 VIGENERE_ENC, VIGENERE_DEC, XOR_MODE, SHA256_MODE
60 const char *key = NULL;
62 static struct option long_opts[] = {
63 {
"encrypt", required_argument, 0,
'e'},
64 {
"decrypt", required_argument, 0,
'd'},
65 {
"crack", no_argument, 0,
'c'},
66 {
"vigenere", no_argument, 0,
'v'},
67 {
"vdecrypt", no_argument, 0,
'V'},
68 {
"xor", no_argument, 0,
'x'},
69 {
"sha256", no_argument, 0,
's'},
70 {
"key", required_argument, 0,
'k'},
71 {
"help", no_argument, 0,
'h'},
76 while ((opt = getopt_long(argc, argv,
"e:d:cvVxsk:h", long_opts, NULL)) != -1) {
78 case 'e': mode = CAESAR_ENC; shift = atoi(optarg);
break;
79 case 'd': mode = CAESAR_DEC; shift = atoi(optarg);
break;
80 case 'c': mode = CAESAR_CRACK;
break;
81 case 'v': mode = VIGENERE_ENC;
break;
82 case 'V': mode = VIGENERE_DEC;
break;
83 case 'x': mode = XOR_MODE;
break;
84 case 's': mode = SHA256_MODE;
break;
85 case 'k': key = optarg;
break;
86 case 'h':
print_usage(argv[0]);
return EXIT_SUCCESS;
96 char *text =
join_args(argc, argv, optind);
98 fprintf(stderr,
"Error: no text supplied or out of memory\n");
101 size_t text_len = strlen(text);
102 int rc = EXIT_SUCCESS;
107 printf(
"%s\n", text);
111 printf(
"%s\n", text);
115 printf(
"Guessed shift: %d\n", guessed);
116 char *copy = strdup(text);
119 printf(
"Decrypted: %s\n", copy);
127 fprintf(stderr,
"Error: --key=KEY is required for Vigenère.\n");
133 printf(
"%s\n", text);
137 fprintf(stderr,
"Error: --key=KEY is required for XOR.\n");
141 xor_apply((
unsigned char *)text, text_len,
142 (
const unsigned char *)key, strlen(key));
144 for (
size_t i = 0; i < text_len; i++) {
145 printf(
"%02x", (
unsigned char)text[i]);
153 sha256((
const uint8_t *)text, text_len, digest);
static void print_usage(const char *prog)
static char * join_args(int argc, char *argv[], int start)
int caesar_crack(const char *text)
Crack a Caesar cipher by chi-squared comparison against English letter frequencies.
void caesar_decrypt(char *text, int shift)
Decrypt a string encrypted with Caesar cipher.
void caesar_encrypt(char *text, int shift)
Encrypt a string using the Caesar cipher.
Caesar cipher encryption and decryption.
void sha256(const uint8_t *data, size_t len, uint8_t digest[SHA256_DIGEST_BYTES])
void sha256_to_hex(const uint8_t digest[SHA256_DIGEST_BYTES], char hex_out[SHA256_HEX_BYTES])
Pure-C SHA-256 implementation, written from the FIPS 180-4 spec.
#define SHA256_DIGEST_BYTES
void vigenere_decrypt(char *text, const char *key)
void vigenere_encrypt(char *text, const char *key)
Vigenère cipher — polyalphabetic shift keyed by a string.
void xor_apply(unsigned char *text, size_t len, const unsigned char *key, size_t keylen)
XOR stream cipher — repeating key.