Break the ciphertext in blocks and attempt to decipher it
This commit is contained in:
parent
504e6820f2
commit
0bce806ec6
3 changed files with 48 additions and 4 deletions
|
@ -48,6 +48,11 @@ int main(int argc, char *argv[]) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (fclose(fp)) {
|
||||
printf("Error closing file %s\n", filename);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
unsigned char buf[BUF_SIZE] = {0};
|
||||
size_t len = base64_to_bytes(buf, input);
|
||||
if (len == 0) {
|
||||
|
@ -67,10 +72,23 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
printf("keysize = %u, min edit distance = %f\n", keysize, min_edit_dist);
|
||||
|
||||
if (fclose(fp)) {
|
||||
printf("Error closing file %s\n", filename);
|
||||
return EXIT_FAILURE;
|
||||
size_t blocks_count = 1 + len / keysize;
|
||||
unsigned char blocks[keysize][blocks_count];
|
||||
memset(blocks, 0, blocks_count * keysize);
|
||||
|
||||
for (size_t i = 0; i < blocks_count; ++i) {
|
||||
for (size_t j = 0; j < keysize; ++j) {
|
||||
blocks[j][i] = buf[i * keysize + j];
|
||||
}
|
||||
}
|
||||
|
||||
char key[keysize];
|
||||
for (size_t j = 0; j < keysize; ++j) {
|
||||
printf("Guessing key character %2zu: ", j);
|
||||
key[j] = best_single_char_xor_key(blocks_count, blocks[j]);
|
||||
printf("%c\n", key[j]);
|
||||
}
|
||||
printf("key: %s\n", key);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
27
src/utils.c
27
src/utils.c
|
@ -2,6 +2,7 @@
|
|||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define min(a, b) \
|
||||
({ \
|
||||
|
@ -39,7 +40,8 @@ size_t hex_to_bytes(unsigned char out[static 1], const char hex[static 1]) {
|
|||
static const char base64_table[65] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
char *bytes_to_base64(char out[static 4], const unsigned char in[static 3], size_t len) {
|
||||
char *bytes_to_base64(char out[static 4], const unsigned char in[static 3],
|
||||
size_t len) {
|
||||
for (size_t i = 0; i < len - 2; i += 3) {
|
||||
size_t j = i / 3 * 4;
|
||||
out[j] = base64_table[in[i] >> 2];
|
||||
|
@ -133,3 +135,26 @@ unsigned int hamming(const char s1[static 1], const char s2[static 1]) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
char best_single_char_xor_key(size_t len, unsigned char buf[static len]) {
|
||||
char cur[len];
|
||||
double min_score = INFINITY;
|
||||
char key = 'X';
|
||||
|
||||
for (char c = 32; c < 127; ++c) {
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
cur[i] = buf[i] ^ c;
|
||||
}
|
||||
double score = frequency_score(len, cur);
|
||||
//printf("current character: %c, current score: %f\n", c, score);
|
||||
if (score < min_score) {
|
||||
min_score = score;
|
||||
key = c;
|
||||
}
|
||||
if (isfinite(min_score)) {
|
||||
printf("current best character: %c, current best score: %f\n", key, min_score);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
|
|
@ -9,5 +9,6 @@ char *bytes_to_base64(char out[static 4], const unsigned char in[static 3], size
|
|||
size_t base64_to_bytes(unsigned char out[static 3], const char in[static 4]);
|
||||
double frequency_score(size_t len, const char buf[static len]);
|
||||
unsigned int hamming(const char s1[static 1], const char s2[static 1]);
|
||||
char best_single_char_xor_key(size_t len, unsigned char buf[static len]);
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue