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;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fclose(fp)) {
|
||||||
|
printf("Error closing file %s\n", filename);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char buf[BUF_SIZE] = {0};
|
unsigned char buf[BUF_SIZE] = {0};
|
||||||
size_t len = base64_to_bytes(buf, input);
|
size_t len = base64_to_bytes(buf, input);
|
||||||
if (len == 0) {
|
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);
|
printf("keysize = %u, min edit distance = %f\n", keysize, min_edit_dist);
|
||||||
|
|
||||||
if (fclose(fp)) {
|
size_t blocks_count = 1 + len / keysize;
|
||||||
printf("Error closing file %s\n", filename);
|
unsigned char blocks[keysize][blocks_count];
|
||||||
return EXIT_FAILURE;
|
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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
27
src/utils.c
27
src/utils.c
|
@ -2,6 +2,7 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define min(a, b) \
|
#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] =
|
static const char base64_table[65] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"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) {
|
for (size_t i = 0; i < len - 2; i += 3) {
|
||||||
size_t j = i / 3 * 4;
|
size_t j = i / 3 * 4;
|
||||||
out[j] = base64_table[in[i] >> 2];
|
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;
|
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]);
|
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]);
|
double frequency_score(size_t len, const char buf[static len]);
|
||||||
unsigned int hamming(const char s1[static 1], const char s2[static 1]);
|
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 */
|
#endif /* UTILS_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue