Cryptopals: 1-4 in python

Challenge 1-4 Detect single-character XOR

Description

One of the 60-character strings in this file has been encrypted by single-character XOR.

Find it.

(Your code from #3 should help.)

Solution

Approach:

Eh, i already have the code for this. Let’s just read in the file and pass each line to the same functions, then get the highest scored line and print it.

Full code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# convert.py
import sys
import heapq
import string

sys.path.append('lib')

from cryptopals import xor_string_with_key, hex_to_dec

letter_multipliers = {
    'e': 10,
    't': 9,
    'a': 8,
    'o': 7,
    'i': 6,
    'n': 5,
    's': 4,
    'r': 3,
    'h': 2,
    'd': 1,
}

def score_string(str):
    score = 0
    for i in range(0, len(str), 1):
        c = str[i]
        if c in letter_multipliers:
            score += letter_multipliers[c]
    return score

def get_most_likely(str):
    key_scores = []
    for i in range(33, 127, 1):
        key = hex(i).replace("0x", "")
        hex_actual = xor_string_with_key(str, key)
        ascii_actual = ""
        for i in range(0, len(hex_actual), 2):
            h = hex_actual[i:i+2]
            # print("{}: {}").format(i, h)
            d = hex_to_dec(h)
            c = chr(d)
            ascii_actual += c
        score = score_string(ascii_actual)
        heapq.heappush(key_scores,
            (
                score,
                (
                    key,
                    ascii_actual
                )
            )
        )
    return heapq.nlargest(1, key_scores)

def get_n_most_likely(n):
    hash_scores = []
    with open('data.txt', 'r') as f:
        for hash in f:
            hash = hash.replace("\n", "")
            most_likely = get_most_likely(hash)
            heapq.heappush(hash_scores, most_likely)
    f.close()
    return heapq.nlargest(n, hash_scores)

def main():
    n_hashes = 1
    most_likely = get_n_most_likely(n_hashes)
    print("top {} most likely...").format(n_hashes)
    print(most_likely)

if __name__ == "__main__":
    main()

Which yields the following output:

1
2
3
$ python convert.py
top 1 most likely...
[[(97, ('35', 'Now that the party is jumping\n'))]]
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy