Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 60 lines (46 sloc) 2.251 kb
f16b361 @asweigart Initial commit.
authored
1 # Affine Cipher Breaker
2 # http://inventwithpython.com/codebreaker (BSD Licensed)
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
3
39ce3a5 @asweigart More changes due to creating new unit tests.
authored
4 import pyperclip, affineCipher, detectEnglish, cryptomath
f16b361 @asweigart Initial commit.
authored
5
dd74989 @asweigart More changes from unit testing
authored
6 SILENT_MODE = False
7
f16b361 @asweigart Initial commit.
authored
8 def main():
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
9 # You might want to copy & paste this text from the source code at
24fc561 @asweigart Changes from unit testing.
authored
10 # http://invpy.com/affineBreaker.py
f16b361 @asweigart Initial commit.
authored
11 myMessage = 'H RZPEDYBO NZDKW WBTBOIB YZ MB RHKKBW VUYBKKVLBUY VG VY RZDKW WBRBVIB H QDPHU VUYZ MBKVBIVUL YQHY VY NHT QDPHU. -HKHU YDOVUL'
12
13 brokenCiphertext = breakAffine(myMessage.upper())
14
15 if brokenCiphertext != None:
16 # The plaintext is displayed on the screen. For the convenience of
17 # the user, we copy the text of the code to the clipboard.
18 print('Copying broken ciphertext to clipboard:')
d95e7da @asweigart Changes made while making unit tests.
authored
19 print(brokenCiphertext)
f16b361 @asweigart Initial commit.
authored
20 pyperclip.copy(brokenCiphertext)
21 else:
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
22 print('Failed to break encryption.')
f16b361 @asweigart Initial commit.
authored
23
24
25 def breakAffine(message):
26 print('Breaking...')
27
28 # Python programs can be stopped at any time by pressing Ctrl-C (on
29 # Windows) or Ctrl-D (on Mac and Linux)
30 print('(Press Ctrl-C or Ctrl-D to quit at any time.)')
31
32 # brute force by looping through every possible key
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
33 for keyA in range(len(affineCipher.LETTERS)):
39ce3a5 @asweigart More changes due to creating new unit tests.
authored
34 if cryptomath.gcd(keyA, len(affineCipher.LETTERS)) != 1:
f16b361 @asweigart Initial commit.
authored
35 continue
36
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
37 for keyB in range(len(affineCipher.LETTERS)):
f16b361 @asweigart Initial commit.
authored
38 decryptedText = affineCipher.decryptMessage(keyA, keyB, message)
dd74989 @asweigart More changes from unit testing
authored
39 if not SILENT_MODE:
40 print('Tried KeyA %s, KeyB %s... (%s)' % (keyA, keyB, decryptedText[:40]))
f16b361 @asweigart Initial commit.
authored
41
42 if detectEnglish.isEnglish(decryptedText):
43 # Check with the user if the decrypted key has been found.
44 print()
45 print('Possible encryption break:')
46 print('KeyA: %s, KeyB: %s' % (keyA, keyB))
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
47 print('Decrypted message: ' + decryptedText[:200])
f16b361 @asweigart Initial commit.
authored
48 print()
49 print('Enter D for done, or just press Enter to continue breaking:')
50 response = input('> ')
51
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
52 if response.strip().upper().startswith('D'):
f16b361 @asweigart Initial commit.
authored
53 return decryptedText
54 return None
55
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
56
57 # If affineBreaker.py is run (instead of imported as a module) call
58 # the main() function.
f16b361 @asweigart Initial commit.
authored
59 if __name__ == '__main__':
60 main()
Something went wrong with that request. Please try again.