2014-10-07 14:44:17 -04:00

85 lines
1.9 KiB
Python

#!/usr/bin/env python
__author__ = "bt3gl"
import string
FREQ_ENGLISH = [0.0749, 0.0129, 0.0354, 0.0362, 0.1400, 0.0218, 0.0174, 0.0422, 0.0665, 0.0027, 0.0047, 0.0357,
0.0339, 0.0674, 0.0737, 0.0243, 0.0026, 0.0614, 0.0695, 0.0985, 0.0300, 0.0116, 0.0169, 0.0028,
0.0164, 0.0004]
def delta(freq_word, freq_eng):
# zip together the value from the text and the value from FREQ_EdiffGlist_freqISH
diff = 0.0
for a, b in zip(freq_word, freq_eng):
diff += abs(a - b)
return diff
def cipher(msg, key):
# Make the cipher
dec = ''
for c in msg.lower():
if 'a' <= c <= 'z':
dec += chr(ord('a') + (ord(c) - ord('a') + key) % 26)
else:
dec += c
return dec
def frequency(msg):
# Compute the word frequencies
dict_freq = dict([(c,0) for c in string.lowercase])
diff = 0.0
for c in msg:
if 'a'<= c <= 'z':
diff += 1
dict_freq[c] += 1
list_freq = dict_freq.items()
list_freq.sort()
return [b / diff for (a, b) in list_freq]
def decipher(msg):
# Decipher by frequency
min_delta = 1000
best_rotation = 0
freq = frequency(msg)
for key in range(26):
d = delta(freq, FREQ_ENGLISH)
if d < min_delta:
min_delta = d
best_rotation = key
return cipher(msg, -best_rotation)
def decipher_simple(msg):
# very smart way of solving using translate and maketrans methods
diff = (ord('t') - ord(s[0])) % 26
x = string.ascii_lowercase
x = x[diff:] + x[:diff]
ans = string.translate(s,string.maketrans(string.ascii_lowercase,x))
return ans
if __name__ == '__main__':
key = 13
text = 'hacker school is awesome!'
cip = cipher(text, key)
dec = decipher(cip)
print "Cipher: " + cip
print "Decipher: " + dec
assert(text == dec)