Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 79 lines (60 sloc) 2.389 kb
f16b361b »
2012-08-19 Initial commit.
1 # Affine Cipher
2 # http://inventwithpython.com/codebreaker (BSD Licensed)
3 import sys, random, pyperclip
4
5 SYMBOLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
6
7
8 def main():
9 message = 'A COMPUTER WOULD DESERVE TO BE CALLED INTELLIGENT IF IT COULD DECEIVE A HUMAN INTO BELIEVING THAT IT WAS HUMAN. -ALAN TURING'
10 keyA, keyB = 5, 7
11 mode = 'encrypt' # set to 'encrypt' or 'decrypt'
12
13 message = message.upper()
14
15 if keyA == 1:
16 sys.exit('The affine cipher becomes incredibly weak when keyA is set to 1. Choose a different key.')
17 if keyB == 0:
18 sys.exit('The affine cipher becomes incredibly weak when keyB is set to 0. Choose a different key.')
19 if gcd(keyA, len(SYMBOLS)) != 1:
20 sys.exit('The key (%s) and the size of the alphabet (%s) are not relatively prime. Choose a different key.' % (key, len(SYMBOLS)))
21
22 print('Original text:')
23 print(message)
24
25 if mode == 'encrypt':
26 translated = encryptMessage(keyA, keyB, message)
27 elif mode == 'decrypt':
28 translated = decryptMessage(keyA, keyB, message)
29
30 print('%sed text:' % (mode.title()))
31 print(translated)
32 pyperclip.copy(translated)
33 print('%sed text copied to clipboard.' % (mode.title()))
34
35
36 def gcd(a, b):
37 # Return the Greatest Common Divisor of a and b.
38 while a != 0:
39 a, b = b % a, a
40 return b
41
42
43 def findModInverse(a, m):
44 for b in range(m):
45 if (a * b) % m == 1:
46 return b
47 return None # None is returned only when gcd(a, m) == 1, which is invalid.
48
49
50 def encryptMessage(keyA, keyB, message):
51 ciphertext = ''
52 for symbol in message:
53 symIndex = SYMBOLS.find(symbol)
54 if symIndex != -1:
55 # encrypt this symbol
56 ciphertext += SYMBOLS[(symIndex * keyA + keyB) % len(SYMBOLS)]
57 else:
58 # just append this symbol unencrypted
59 ciphertext += symbol
60 return ciphertext
61
62
63 def decryptMessage(keyA, keyB, message):
64 plaintext = ''
65 modInverseOfKeyA = findModInverse(keyA, len(SYMBOLS))
66
67 for symbol in message:
68 symIndex = SYMBOLS.find(symbol)
69 if symIndex != -1:
70 # decrypt this symbol
71 plaintext += SYMBOLS[(symIndex - keyB) * modInverseOfKeyA % len(SYMBOLS)]
72 else:
73 # just append this symbol unencrypted
74 plaintext += symbol
75 return plaintext
76
77
78 if __name__ == '__main__':
79 main()
Something went wrong with that request. Please try again.