C Fundamentals
Algorithms · data structures · cryptography · systems — pure C11, zero deps
Loading...
Searching...
No Matches
algorithms/encryption/main.c
Go to the documentation of this file.
1/**
2 * @file main.c
3 * @brief CLI for Caesar / Vigenère / XOR ciphers + SHA-256 hashing.
4 *
5 * Usage:
6 * crypto-cli -e SHIFT "text" # Caesar encrypt
7 * crypto-cli -d SHIFT "text" # Caesar decrypt
8 * crypto-cli -c "ciphertext" # Caesar crack via chi-squared
9 * crypto-cli -v --key=KEY "text" # Vigenère encrypt
10 * crypto-cli -V --key=KEY "ciphertext" # Vigenère decrypt
11 * crypto-cli -x --key=KEY "text" # XOR (encrypt = decrypt)
12 * crypto-cli -s "text" # SHA-256 → hex
13 */
14
15#include "caesar.h"
16#include "sha256.h"
17#include "vigenere.h"
18#include "xor_cipher.h"
19#include <getopt.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24static void print_usage(const char *prog) {
25 printf("Usage:\n");
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);
33}
34
35static char *join_args(int argc, char *argv[], int start) {
36 if (start >= argc) return NULL;
37 size_t total = 0;
38 for (int i = start; i < argc; i++) total += strlen(argv[i]) + 1;
39 char *buf = malloc(total + 1);
40 if (!buf) return NULL;
41 buf[0] = '\0';
42 for (int i = start; i < argc; i++) {
43 if (i > start) strcat(buf, " ");
44 strcat(buf, argv[i]);
45 }
46 return buf;
47}
48
49int main(int argc, char *argv[]) {
50 if (argc < 2) {
51 print_usage(argv[0]);
52 return EXIT_FAILURE;
53 }
54
55 enum {
56 NONE, CAESAR_ENC, CAESAR_DEC, CAESAR_CRACK,
57 VIGENERE_ENC, VIGENERE_DEC, XOR_MODE, SHA256_MODE
58 } mode = NONE;
59 int shift = 0;
60 const char *key = NULL;
61
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'},
72 {0, 0, 0, 0}
73 };
74
75 int opt;
76 while ((opt = getopt_long(argc, argv, "e:d:cvVxsk:h", long_opts, NULL)) != -1) {
77 switch (opt) {
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;
87 default: print_usage(argv[0]); return EXIT_FAILURE;
88 }
89 }
90
91 if (mode == NONE) {
92 print_usage(argv[0]);
93 return EXIT_FAILURE;
94 }
95
96 char *text = join_args(argc, argv, optind);
97 if (!text) {
98 fprintf(stderr, "Error: no text supplied or out of memory\n");
99 return EXIT_FAILURE;
100 }
101 size_t text_len = strlen(text);
102 int rc = EXIT_SUCCESS;
103
104 switch (mode) {
105 case CAESAR_ENC:
106 caesar_encrypt(text, shift);
107 printf("%s\n", text);
108 break;
109 case CAESAR_DEC:
110 caesar_decrypt(text, shift);
111 printf("%s\n", text);
112 break;
113 case CAESAR_CRACK: {
114 int guessed = caesar_crack(text);
115 printf("Guessed shift: %d\n", guessed);
116 char *copy = strdup(text);
117 if (copy) {
118 caesar_decrypt(copy, guessed);
119 printf("Decrypted: %s\n", copy);
120 free(copy);
121 }
122 break;
123 }
124 case VIGENERE_ENC:
125 case VIGENERE_DEC:
126 if (!key) {
127 fprintf(stderr, "Error: --key=KEY is required for Vigenère.\n");
128 rc = EXIT_FAILURE;
129 break;
130 }
131 if (mode == VIGENERE_ENC) vigenere_encrypt(text, key);
132 else vigenere_decrypt(text, key);
133 printf("%s\n", text);
134 break;
135 case XOR_MODE: {
136 if (!key) {
137 fprintf(stderr, "Error: --key=KEY is required for XOR.\n");
138 rc = EXIT_FAILURE;
139 break;
140 }
141 xor_apply((unsigned char *)text, text_len,
142 (const unsigned char *)key, strlen(key));
143 /* Print as hex since output may contain non-printable bytes. */
144 for (size_t i = 0; i < text_len; i++) {
145 printf("%02x", (unsigned char)text[i]);
146 }
147 printf("\n");
148 break;
149 }
150 case SHA256_MODE: {
151 uint8_t digest[SHA256_DIGEST_BYTES];
152 char hex[SHA256_HEX_BYTES];
153 sha256((const uint8_t *)text, text_len, digest);
154 sha256_to_hex(digest, hex);
155 printf("%s\n", hex);
156 break;
157 }
158 case NONE:
159 break;
160 }
161
162 free(text);
163 return rc;
164}
static void print_usage(const char *prog)
static char * join_args(int argc, char *argv[], int start)
int main(void)
Definition benchmark.c:50
int caesar_crack(const char *text)
Crack a Caesar cipher by chi-squared comparison against English letter frequencies.
Definition caesar.c:38
void caesar_decrypt(char *text, int shift)
Decrypt a string encrypted with Caesar cipher.
Definition caesar.c:36
void caesar_encrypt(char *text, int shift)
Encrypt a string using the Caesar cipher.
Definition caesar.c:27
Caesar cipher encryption and decryption.
void sha256(const uint8_t *data, size_t len, uint8_t digest[SHA256_DIGEST_BYTES])
Definition sha256.c:66
void sha256_to_hex(const uint8_t digest[SHA256_DIGEST_BYTES], char hex_out[SHA256_HEX_BYTES])
Definition sha256.c:112
Pure-C SHA-256 implementation, written from the FIPS 180-4 spec.
#define SHA256_HEX_BYTES
Definition sha256.h:17
#define SHA256_DIGEST_BYTES
Definition sha256.h:16
void vigenere_decrypt(char *text, const char *key)
Definition vigenere.c:34
void vigenere_encrypt(char *text, const char *key)
Definition vigenere.c:33
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)
Definition xor_cipher.c:7
XOR stream cipher — repeating key.