Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 70 lines (53 sloc) 2.426 kb
f16b361 @asweigart Initial commit.
authored
1 # Affine Cipher
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 sys, pyperclip, cryptomath
f16b361 @asweigart Initial commit.
authored
5
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
6 LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
f16b361 @asweigart Initial commit.
authored
7
8
9 def main():
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
10 myMessage = 'A computer would deserve to be called intelligent if it could deceive a human into believing that it was human. -Alan Turing'
11 myKeyA, myKeyB = 5, 7
12 myMode = 'encrypt' # set to 'encrypt' or 'decrypt'
f16b361 @asweigart Initial commit.
authored
13
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
14 myMessage = myMessage.upper()
f16b361 @asweigart Initial commit.
authored
15
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
16 if myMode == 'encrypt':
17 translated = encryptMessage(myKeyA, myKeyB, myMessage)
18 elif myMode == 'decrypt':
19 translated = decryptMessage(myKeyA, myKeyB, myMessage)
f16b361 @asweigart Initial commit.
authored
20
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
21 print('%sed text:' % (myMode.title()))
f16b361 @asweigart Initial commit.
authored
22 print(translated)
23 pyperclip.copy(translated)
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
24 print('Full %sed text copied to clipboard.' % (myMode))
f16b361 @asweigart Initial commit.
authored
25
26
27 def encryptMessage(keyA, keyB, message):
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
28 # key strength and validity checks
29 if keyA == 1:
30 sys.exit('The affine cipher becomes incredibly weak when keyA is set to 1. Choose a different key.')
31 if keyB == 0:
32 sys.exit('The affine cipher becomes incredibly weak when keyB is set to 0. Choose a different key.')
d95e7da @asweigart Changes made while making unit tests.
authored
33
39ce3a5 @asweigart More changes due to creating new unit tests.
authored
34 if cryptomath.gcd(keyA, len(LETTERS)) != 1:
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
35 sys.exit('The key (%s) and the size of the alphabet (%s) are not relatively prime. Choose a different key.' % (keyA, len(LETTERS)))
36
f16b361 @asweigart Initial commit.
authored
37 ciphertext = ''
38 for symbol in message:
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
39 if symbol in LETTERS:
f16b361 @asweigart Initial commit.
authored
40 # encrypt this symbol
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
41 symIndex = LETTERS.find(symbol)
42 ciphertext += LETTERS[(symIndex * keyA + keyB) % len(LETTERS)]
f16b361 @asweigart Initial commit.
authored
43 else:
44 # just append this symbol unencrypted
45 ciphertext += symbol
46 return ciphertext
47
48
49 def decryptMessage(keyA, keyB, message):
39ce3a5 @asweigart More changes due to creating new unit tests.
authored
50 if cryptomath.gcd(keyA, len(LETTERS)) != 1:
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
51 sys.exit('The key (%s) and the size of the alphabet (%s) are not relatively prime. Choose a different key.' % (keyA, len(LETTERS)))
52
f16b361 @asweigart Initial commit.
authored
53 plaintext = ''
39ce3a5 @asweigart More changes due to creating new unit tests.
authored
54 modInverseOfKeyA = cryptomath.findModInverse(keyA, len(LETTERS))
f16b361 @asweigart Initial commit.
authored
55
56 for symbol in message:
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
57 if symbol in LETTERS:
f16b361 @asweigart Initial commit.
authored
58 # decrypt this symbol
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
59 symIndex = LETTERS.find(symbol)
60 plaintext += LETTERS[(symIndex - keyB) * modInverseOfKeyA % len(LETTERS)]
f16b361 @asweigart Initial commit.
authored
61 else:
62 # just append this symbol unencrypted
63 plaintext += symbol
64 return plaintext
65
66
91f8abb @asweigart First round of personal fixes. This is an unhelpful log message.
authored
67 # If affineCipher.py is run (instead of imported as a module) call
68 # the main() function.
f16b361 @asweigart Initial commit.
authored
69 if __name__ == '__main__':
70 main()
Something went wrong with that request. Please try again.