Chapter 8 暗号解読¶
from railfence import *
cipherText = "n aci mreidontoowp mgorw"
for i in range(2, len(cipherText) + 1):
print(railDecrypt(cipherText, i))
def createWordDict(dName):
myDict = {}
with open(dName, 'r') as myFile:
for line in myFile:
myDict[line[:-1]] = True # set all values to True
return myDict
def railBreak(cipherText):
wordDict = createWordDict('wordlist.txt')
cipherLen = len(cipherText)
maxGoodSoFar = 0
bestGuess = "No words found in dictionary" # default response
for i in range(2, cipherLen + 1):
words = railDecrypt(cipherText, i)
goodCount = 0 # reset for new list
for w in words:
if w in wordDict:
goodCount = goodCount + 1
if goodCount > maxGoodSoFar: # if more words in this list
maxGoodSoFar = goodCount
bestGuess = " ".join(words) # join words in list with space
return bestGuess
from railfence import *
cipherText = "n aci mreidontoowp mgorw"
print(railBreak(cipherText))
def railDecrypt(cipherText, numRails):
railLen = len(cipherText) // numRails
solution = ''
for col in range(railLen):
for rail in range(numRails):
nextLetter = col + (rail * railLen)
solution = solution + cipherText[nextLetter]
return solution.split()
def removeMatches(myString, removeString):
newStr = " "
for ch in myString:
if ch not in removeString:
newStr = newStr + ch
return newStr
text = 'Are there 25, 26, or 27 non-letters to remove?'
text = text.lower()
text
nonLetters = removeMatches(text, 'abcdefghijklmnopqrstuvwxyz')
print(nonLetters)
text = removeMatches(text, nonLetters)
print(text)
def letterFrequency(text):
text = text.lower()
nonLetters = removeMatches(text, 'abcdefghijklmnopqrstyvwxyz')
text = removeMatches(text, nonLetters)
lCount = {}
total = len(text)
for ch in text: # cont each letter's occurrence
lCount[ch] = lCount.get(ch, 0) + 1
for ch in lCount: # calculate percentages
lCount[ch] = lCount[ch] / total
return lCount
with open('wells.txt', 'r', encoding='utf-8') as wells:
text = wells.read()
lf = letterFrequency(text)
for letter in 'abcdefghijklmnopqrstuvwxyz':
print(letter, lf.get(letter))
xList = [3, 7, 4, 9]
xList.sort(reverse=True)
xList
def getFreq(t):
return t[1] # return second item in the tuple
lfList = list(lf.items())
lfList.sort(key=getFreq, reverse=True)
for empty in lfList: # each entry is a tuple
print("{0} {1:.3f}".format(empty[0], empty[1]))
def maybeAdd(ch, toList):
if ch in 'abcdefghijklmnnopqrstyvwxyz' and ch not in toList:
toList.append(ch)
myList = []
maybeAdd('a', myList) # a is a letter and not in the list
print(myList)
maybeAdd('-', myList) # - is not a letter
print(myList)
maybeAdd('b', myList) # b is a letter and not in the list
print(myList)
maybeAdd('a', myList) # a is already in the list
print(myList)
def neighborCount(text):
nbDict = {}
text = text.lower()
for i in range(len(text) - 1):
nbList = nbDict.setdefault(text[i], [])
maybeAdd(text[i + 1], nbList)
nbList = nbDict.setdefault(text[i + 1], [])
maybeAdd(text[i], nbList)
for key in nbDict.keys(): # replace letters list with count
nbDict[key] = len(nbDict.get(key))
return nbDict
nbList = nbDict.get(text[i])
if nbList == None:
nbDict[text[i]] = []
nbList = nbDict[text[i]]
freqDict = neighborCount(text)
for i in 'ent':
print(i, freqDict[i])
def maybeAdd(ch, toDict):
if ch in 'abcdefghijklmnopqrstyvwxyz':
toDict[ch] = toDict.setdefault(ch, 0) + 1
def neighborCount(text):
nbDict = {}
text = text.lower()
for i in range(len(text) - 1):
nbList = nbDict.setdefault(text[i], {})
maybeAdd(text[i + 1], nbList)
nbList = nbDict.setdefault(text[i + 1], {})
maybeAdd(text[i], nbList)
return nbDict
d = neighborCount(text)
print(d['e'])
print(d['n'])
print(d['t'])
{'h': 10434, 'c': 705, 'u': 1712, 'e': 3143, 'i': 4156, 's': 3095, 'a': 3847,
'o': 3163, 'r': 1884, 'n': 1744, 'l': 586, 'f': 282, 'w': 215, 't': 864, 'y':
298, 'm': 80, 'p': 194, 'x': 84, 'b': 34, 'g': 29, 'd': 2}
cipherText = cipherText.replace('l', 'E')
cipherText = cipherText.replace('h', 'A')
cipherText
def sortByLen(w):
return len(w)
cipherWords = cipherText.split()
cipherWords.sort(key=sortByLen)
cipherWords
cipherText = cipherText.replace('b', 'N')
cipherText = cipherText.replace('e', 'D')
cipherText = cipherText.replace('k', 'T')
cipherText = cipherText.replace('u', 'H')
cipherText
import re
re.match('.ADE', 'FADE')
re.match('.ADE', 'FADER')
re.match('.ADE$', 'FADER')
re.match('.ADE$', 'ADE')
re.match('.ADE$', 'FUDE')
def checkWord(regex):
resList = []
with open('wordlist.txt', 'r') as wordFile:
for line in wordFile:
if re.match(regex, line[: -1]):
resList.append(line[:-1])
return resList
checkWord('.o.ning')
checkWord(' [bcjkmpqruvwxyz]o[bcjkmpqruvwxyz]ning')
checkWord('a..i.al')
checkWord('a..i.al$')
['admiral', 'arrival']
checkWord('a [bcjkmpqruvwxyz] [bcjkmpqruvwxyz]i[bcjkmpqruvwxyz]al$')
def checkWord(unused, pattern):
resList = []
with open('wordlist.txt', 'r') as wordFile:
rePat = '['+unused+']'
regex = re.sub('[a-z]', rePat, pattern) + '$'
regex = regex.lower()
print('matching', regex)
for line in wordFile:
if re.match(regex, line[:-1]):
resList.append(line[:-1])
return resList
checkWord('bcjkmpqruvwxyz', 'WONDEiFmLLq')
checkWord('bcjkmpqruvwxyz', 'AiiInAL')
checkWord('bcjkmpqruvwxyz', 'mNmSmAL')
cg = re.match('F(..)L(..)', 'FOILED')
cg
cg.group(1)
cg.group(2)
cg = re.match('F(..)L(..)', 'FOOLER')
cg.groups()
def findLetters(unused, pattern):
resList = []
with open('wordlist.txt', 'r') as wordFile:
ctLetters = re.findall('[a-z]', pattern)
print(ctLetters)
rePat = '(['+unused+'])'
regex = re.sub('[a-z]', rePat, pattern) + '$'
regex = regex.lower()
for line in wordFile:
myMatch = re.match(regex, line[:-1])
if myMatch:
matchingLetters = myMatch.groups()
matchList = []
for l in matchingLetters:
matchList.append(l.upper())
resList.append(line[:-1])
resList.append(list(zip(ctLetters, matchList)))
return resList
re.findall('[123]', '1,234') # find single characters
re.findall('[1234] +', '1,234') # find multiple characters
re.findall('[A-Z]', 'Hello World') # find capital letters
list(zip([1, 2, 3], [4, 5, 6]))
list(zip(['a', 'b', 'c'], ['Z', 'Y', 'X']))
list(zip(['a', 'b', 'c'], ['Z', 'Y', 'X'], [1, 2, 3]))
findLetters('bcjkmpqruvwxyz', 'AiiInAL') # i -> r, n -> V
['arrival', [('i', 'R'), ('i', 'R'), ('n', 'V')]]
findLetters('bcjkmpqruvwxyz', 'ALiEADq') # g -> Y
findLetters('bcjkmpqruvwxyz', 'giEErE') # g -> B, r -> Z
findLetters('bcjkmpqruvwxyz', 'mNmSmAL') # m -> U
cipherText = cipherText.replace('i', 'R')
cipherText = cipherText.replace('n', 'V')
cipherText = cipherText.replace('q', 'Y')
cipherText = cipherText.replace('g', 'B')
cipherText = cipherText.replace('r', 'Z')
cipherText = cipherText.replace('m', 'U')
findLetters('cjkmpqwx', 'wOaaON') # w ->C?, w ->P?, a -> M
cipherText = cipherText.replace('w', 'C')
cipherText = cipherText.replace('a', 'M')
findLetters('jkpqx', 'dIT') # no definitive substitution
findLetters('jkpqx', 'AddEARANCE') # d -> P
ciphertext = cipherText.replace('d', 'P')
findLetters('jkqx', 'xUST') # x -> J
cipherText = cipherText.replace('x', 'J')