Commit my random junk
[sandbox] / cryptopals-python / cryptopals.py
index 56501a1..24392b8 100644 (file)
@@ -32,6 +32,28 @@ with open('sample.txt','r') as sample_file:
 
 SAMPLE_FREQUENCIES = get_character_frequencies(sample_text)
 
+def encrypt_with_repeating_xor(plaintext, key):
+    plaintext_bytes = plaintext.encode('utf-8')
+    key_bytes = key.encode('utf-8')
+
+    return xor_bytes(
+        plaintext_bytes,
+        (key_bytes * ((len(plaintext_bytes) // len(key_bytes)) + 1))[:len(plaintext_bytes)],
+    )
+
+def hamming_weight(_bytes):
+    def hamming_weight_of_byte(b):
+        count = 0
+        while b > 0:
+            count += 1
+            b &= b - 1
+        return count
+
+    return sum(hamming_weight_of_byte(b) for b in _bytes)
+
+def hamming_distance(bytes0, bytes1):
+    return hamming_weight(xor_bytes(bytes0, bytes1))
+
 class Set1Challenge1Tests(unittest.TestCase):
     def test_converts_hex_to_base64(self):
         expected = 'SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t\n'
@@ -108,5 +130,29 @@ class Set1Challenge4Tests(unittest.TestCase):
 
         self.assertEqual(expected, actual)
 
+class Set1Challenge5Tests(unittest.TestCase):
+    def test_encrypts_with_repeating_xor(self):
+        plaintext = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"
+        key = 'ICE'
+
+        expected = '0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f'
+        actual = encrypt_with_repeating_xor(plaintext, key).hex()
+
+        self.assertEqual(expected, actual)
+
+with open('set1challenge6.txt','r') as f:
+    set1challenge6text = f.read()
+
+class Set1Challenge6Tests(unittest.TestCase):
+    def test_hamming_distance(self):
+        expected = 37
+        actual = hamming_distance(b'this is a test', b'wokka wokka!!!')
+        self.assertEqual(expected, actual)
+
+    def test_find_repeated_xor_keysize(self):
+        expected = 0
+        actual = find_repeated_xor_keysize(set1challenge6text)
+        self.assertEqual(expected, actual)
+
 if __name__ == '__main__':
     unittest.main()