cryptopals

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e071794ffd90ed473d9daeca62388f3d17b45800
parent a8b7ca46b35cc82afa2b64fc2300047e5879836f
Author: mpizzzle <michael.770211@gmail.com>
Date:   Sat,  7 Oct 2017 15:36:52 +0100

set 1 challenge 6 complete

Diffstat:
Mset1/break_repeating_key_xor.py | 50+++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/set1/break_repeating_key_xor.py b/set1/break_repeating_key_xor.py @@ -1,6 +1,50 @@ import sys -def hamming_distance(str1, str2): +frequent_letters = "etaoi ETAOI" + +def distance(str1, str2): return ''.join([bin(ord(a) ^ ord(b)) for a, b in zip(str1, str2)]).count('1') + +def get_candidate_key_length(file, accuracy): + candidate_distance = sys.float_info.max + candidate_length = 0 + + for key_length in range(2, 40): + this_distance = sum([distance(file[key_length * x:key_length * (x + 1)], file[key_length * (x + 1):key_length * (x + 2)]) for x in range(accuracy)]) + average_distance = this_distance / float(key_length * (accuracy)) + if average_distance < candidate_distance: + candidate_distance = average_distance + candidate_length = key_length + + return candidate_length + +def get_candidate_xor_byte(transposed_block): + candidate = '' + candidate_frequency = 0 + + for x in range(128): + frequency = 0 + plaintext = ''.join([chr(x ^ ord(a)) for a in transposed_block]) + + for char in plaintext: + if char in frequent_letters: + frequency += 1 + + if frequency > candidate_frequency: + candidate = chr(x) + candidate_frequency = frequency + return candidate + +def decrypt(key, msg): + return ''.join([chr(ord(key[i % len(key)]) ^ ord(char)) for i, char in enumerate(msg)]) + +with open('files/6.txt') as f: + file = f.read().decode("base64") + +key_length = get_candidate_key_length(file, 10) +split_file = [file[i:i + key_length] for i in range(0, len(file), key_length)] +transposed_blocks = [''.join([block[x] for block in split_file[:len(split_file)- 1]]) for x in range(key_length)] -print hamming_distance("this is a test", "wokka wokka!!!")- \ No newline at end of file +key = ''.join([get_candidate_xor_byte(transposed_block) for transposed_block in transposed_blocks]) +print key +print decrypt(key, file)+ \ No newline at end of file