Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updates from Ari's edits and consistency checks.

  • Loading branch information...
commit 26494d6f5e9efd07d00210845ccd9275bf10916e 1 parent 8b76740
@asweigart authored
View
4 affineCipher.py
@@ -2,7 +2,7 @@
# http://inventwithpython.com/hacking (BSD Licensed)
import sys, pyperclip, cryptomath, random
-SYMBOLS = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""
+SYMBOLS = """ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~""" # note the space at the front
def main():
@@ -62,7 +62,7 @@ def decryptMessage(key, message):
if symbol in SYMBOLS:
# decrypt this symbol
symIndex = SYMBOLS.find(symbol)
- plaintext += SYMBOLS[( (symIndex - keyB) % len(SYMBOLS)) * modInverseOfKeyA % len(SYMBOLS)]
+ plaintext += SYMBOLS[(symIndex - keyB) * modInverseOfKeyA % len(SYMBOLS)]
else:
plaintext += symbol # just append this symbol undecrypted
return plaintext
View
2  affineHacker.py
@@ -29,7 +29,7 @@ def hackAffine(message):
# Windows) or Ctrl-D (on Mac and Linux)
print('(Press Ctrl-C or Ctrl-D to quit at any time.)')
- # brute force by looping through every possible key
+ # brute-force by looping through every possible key
for key in range(len(affineCipher.SYMBOLS) ** 2):
keyA = affineCipher.getKeyParts(key)[0]
if cryptomath.gcd(keyA, len(affineCipher.SYMBOLS)) != 1:
View
2  affineKeyTest.py
@@ -4,7 +4,7 @@
import affineCipher, cryptomath
message = 'Make things as simple as possible, but not simpler.'
-for keyA in range(2, len(affineCipher.SYMBOLS) + 5):
+for keyA in range(2, 100):
key = keyA * len(affineCipher.SYMBOLS) + 1
if cryptomath.gcd(keyA, len(affineCipher.SYMBOLS)) == 1:
View
2  buggy.py
@@ -6,4 +6,4 @@
if answer == number1 + number2:
print('Correct!')
else:
- print('Nope! The answer is ' + str(number1 + number2))
+ print('Nope! The answer is ' + str(number1 + number2))
View
4 caesarCipher.py
@@ -9,7 +9,7 @@
# the encryption/decryption key
key = 13
-# tells the program to encrypt of decrypt
+# tells the program to encrypt or decrypt
mode = 'encrypt' # set to 'encrypt' or 'decrypt'
# every possible symbol that can be encrypted
@@ -31,7 +31,7 @@
elif mode == 'decrypt':
num = num - key
- # handle the wrap around if num is larger than the length of
+ # handle the wrap-around if num is larger than the length of
# LETTERS or less than 0
if num >= len(LETTERS):
num = num - len(LETTERS)
View
4 caesarCipher2.py
@@ -9,7 +9,7 @@
# the encryption/decryption key
key = 13
-# tells the program to encrypt of decrypt
+# tells the program to encrypt or decrypt
mode = 'encrypt' # set to 'encrypt' or 'decrypt'
# every possible symbol that can be encrypted
@@ -31,7 +31,7 @@
elif mode == 'decrypt':
num = num - key
- # handle the wrap around if num is larger than the length of
+ # handle the wrap-around if num is larger than the length of
# LETTERS or less than 0
if num >= len(LETTERS):
num = num - len(LETTERS)
View
2  caesarHacker.py
@@ -19,7 +19,7 @@
num = LETTERS.find(symbol) # get the number of the symbol
num = num - key
- # handle the wrap around if num is 26 or larger of less than 0
+ # handle the wrap-around if num is 26 or larger or less than 0
if num < 0:
num = num + len(LETTERS)
View
29 coinFlips.py
@@ -17,31 +17,4 @@
print()
print('Out of 1000 coin tosses, heads came up ' + str(heads) + ' times!')
-print('Were you close?')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+print('Were you close?')
View
2  detectEnglish.py
@@ -6,7 +6,7 @@
# detectEnglish.isEnglish(someString) # returns True or False
# (There must be a "dictionary.txt" file in this directory with all English
# words in it, one word per line. You can download this from
-# http://invpy.com/dictionary.txt) and put it in the same directory as detectEnglish.py.
+# http://invpy.com/dictionary.txt)
UPPERLETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + ' \t\n'
View
2  makeWordPatterns.py
@@ -1,7 +1,7 @@
# Makes the wordPatterns.py File
# http://inventwithpython.com/hacking (BSD Licensed)
-# Create wordPatterns.py based on the words in our dictionary
+# Creates wordPatterns.py based on the words in our dictionary
# text file, dictionary.txt. (Download this file from
# http://invpy.com/dictionary.txt)
View
2  rabinMiller.py
@@ -58,5 +58,5 @@ def generateLargePrime(keysize=1024):
# Return a random prime number of keysize bits in size.
while True:
num = random.randrange(2**(keysize-1), 2**(keysize))
- if isPrime(num) == True:
+ if isPrime(num):
return num
View
4 rsaCipher.py
@@ -137,7 +137,7 @@ def readFromFileAndDecrypt(messageFilename, keyFilename):
# Read in the message length and the encrypted message from the file.
fo = open(messageFilename)
content = fo.read()
- messageLength, blockSize, message = content.split('_')
+ messageLength, blockSize, encryptedMessage = content.split('_')
messageLength = int(messageLength)
blockSize = int(blockSize)
@@ -147,7 +147,7 @@ def readFromFileAndDecrypt(messageFilename, keyFilename):
# Convert the encrypted message into large int values.
encryptedBlocks = []
- for block in message.split(','):
+ for block in encryptedMessage.split(','):
encryptedBlocks.append(int(block))
# Decrypt the large int values.
View
2  simpleSubDictionaryHacker.py
@@ -26,7 +26,7 @@ def hackSimpleSubDictionary(message):
tryNum = 1
- # brute force by looping through every possible key
+ # brute-force by looping through every possible key
for key in detectEnglish.ENGLISH_WORDS:
if tryNum % 100 == 0 and not SILENT_MODE:
print('%s keys tried. (%s)' % (tryNum, key))
View
20 simpleSubHacker.py
@@ -45,12 +45,12 @@ def addLettersToMapping(letterMapping, cipherword, candidate):
# This function adds the letters of the candidate as potential
# decryption letters for the cipherletters in the cipherletter
# mapping.
- # The letterMapping dictionary is modified in-place.
+ letterMapping = copy.deepcopy(letterMapping)
for i in range(len(cipherword)):
if candidate[i] not in letterMapping[cipherword[i]]:
letterMapping[cipherword[i]].append(candidate[i])
-
+ return letterMapping
def intersectMappings(mapA, mapB):
@@ -84,7 +84,7 @@ def removeSolvedLettersFromMapping(letterMapping):
# to ['M']. Note that now that 'A' maps to only one letter, we can
# remove 'M' from the list of letters for every other
# letter. (This is why there is a loop that keeps reducing the map.)
-
+ letterMapping = copy.deepcopy(letterMapping)
loopAgain = True
while loopAgain:
# First assume that we will not loop again:
@@ -107,13 +107,13 @@ def removeSolvedLettersFromMapping(letterMapping):
if len(letterMapping[cipherletter]) == 1:
# A new letter is now solved, so loop again.
loopAgain = True
- # Nothing is returned because letterMapping is modified in-place.
+ return letterMapping
def hackSimpleSub(message):
intersectedMap = getBlankCipherletterMapping()
- message = nonLettersOrSpacePattern.sub('', message.upper()).split()
- for cipherword in message:
+ cipherwordList = nonLettersOrSpacePattern.sub('', message.upper()).split()
+ for cipherword in cipherwordList:
# Get a new cipherletter mapping for each ciphertext word.
newMap = getBlankCipherletterMapping()
@@ -123,13 +123,13 @@ def hackSimpleSub(message):
# Add the letters of each candidate to the mapping.
for candidate in wordPatterns.allPatterns[wordPattern]:
- addLettersToMapping(newMap, cipherword, candidate)
+ newMap = addLettersToMapping(newMap, cipherword, candidate)
# Intersect the new mapping with the existing intersected mapping.
intersectedMap = intersectMappings(intersectedMap, newMap)
+
# Remove any solved letters from the other lists.
- removeSolvedLettersFromMapping(intersectedMap)
- return intersectedMap
+ return removeSolvedLettersFromMapping(intersectedMap)
def decryptWithCipherletterMapping(ciphertext, letterMapping):
@@ -148,7 +148,7 @@ def decryptWithCipherletterMapping(ciphertext, letterMapping):
ciphertext = ciphertext.replace(cipherletter.upper(), '_')
key = ''.join(key)
- # With the key we've created, decrypt the message.
+ # With the key we've created, decrypt the ciphertext.
return simpleSubCipher.decryptMessage(key, ciphertext)
View
4 transpositionDecrypt.py
@@ -21,9 +21,9 @@ def decryptMessage(key, message):
# "rows" of the grid that the plaintext is written on by using a list
# of strings. First, we need to calculate a few values.
- # The number of "columns" our transposition grid:
+ # The number of "columns" in our transposition grid:
numOfColumns = math.ceil(len(message) / key)
- # The number of "rows" our grid will need:
+ # The number of "rows" in our grid will need:
numOfRows = key
# The number of "shaded boxes" in the last "column" of the grid:
numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)
View
2  transpositionEncrypt.py
@@ -9,7 +9,7 @@ def main():
ciphertext = encryptMessage(myKey, myMessage)
- # Print the (encrypted) string in ciphertext to the screen, with
+ # Print the encrypted string in ciphertext to the screen, with
# a | (called "pipe" character) after it in case there are spaces at
# the end of the encrypted message.
print(ciphertext + '|')
View
2  transpositionFileCipher.py
@@ -30,7 +30,7 @@ def main():
print('%sing...' % (myMode.title()))
- # Measure how long the encryption takes.
+ # Measure how long the encryption/decryption takes.
startTime = time.time()
if myMode == 'encrypt':
translated = transpositionEncrypt.encryptMessage(myKey, content)
View
4 transpositionHacker.py
@@ -1,4 +1,4 @@
-# Transpositional Cipher Hacker
+# Transposition Cipher Hacker
# http://inventwithpython.com/hacking (BSD Licensed)
import pyperclip, detectEnglish, transpositionDecrypt
@@ -25,7 +25,7 @@ def hackTransposition(message):
# Windows) or Ctrl-D (on Mac and Linux)
print('(Press Ctrl-C or Ctrl-D to quit at any time.)')
- # brute force by looping through every possible key
+ # brute-force by looping through every possible key
for key in range(1, len(message)):
print('Trying key #%s...' % (key))
View
2  vigenereCipher.py
@@ -45,7 +45,7 @@ def translateMessage(key, message, mode):
elif mode == 'decrypt':
num -= LETTERS.find(key[keyIndex]) # subtract if decrypting
- num %= len(LETTERS) # handle the potential wrap around
+ num %= len(LETTERS) # handle the potential wrap-around
# add the encrypted/decrypted symbol to the end of translated.
if symbol.isupper():
View
20 vigenereDictionaryHacker.py
@@ -24,16 +24,16 @@ def hackVigenere(ciphertext):
word = word.strip() # remove the newline at the end
decryptedText = vigenereCipher.decryptMessage(word, ciphertext)
if detectEnglish.isEnglish(decryptedText, wordPercentage=40):
- # Check with user to see if the decrypted key has been found.
- print()
- print('Possible encryption break:')
- print('Key ' + str(word) + ': ' + decryptedText[:100])
- print()
- print('Enter D for done, or just press Enter to continue breaking:')
- response = input('> ')
-
- if response.upper().startswith('D'):
- return decryptedText
+ # Check with user to see if the decrypted key has been found.
+ print()
+ print('Possible encryption break:')
+ print('Key ' + str(word) + ': ' + decryptedText[:100])
+ print()
+ print('Enter D for done, or just press Enter to continue breaking:')
+ response = input('> ')
+
+ if response.upper().startswith('D'):
+ return decryptedText
if __name__ == '__main__':
main()
View
20 vigenereHacker.py
@@ -124,9 +124,9 @@ def kasiskiExamination(ciphertext):
# See getMostCommonFactors() for a description of factorsByCount.
factorsByCount = getMostCommonFactors(seqFactors)
- # Now we extract the factor counts from factorsByCount and put them
- # in variables named allLikelyKeyLengths and allLikelyKeyLengthsStr
- # so that they are easier to use later.
+ # Now we extract the factor counts from factorsByCount and
+ # put them in allLikelyKeyLengths so that they are easier to
+ # use later.
allLikelyKeyLengths = []
for twoIntTuple in factorsByCount:
allLikelyKeyLengths.append(twoIntTuple[0])
@@ -134,12 +134,12 @@ def kasiskiExamination(ciphertext):
return allLikelyKeyLengths
-def getNthSubkeysLetter(n, keyLength, message):
+def getNthSubkeysLetters(n, keyLength, message):
# Returns every Nth letter for each keyLength set of letters in text.
- # E.g. getNthSubkeysLetter(1, 3, 'ABCABCABC') returns 'AAA'
- # getNthSubkeysLetter(2, 3, 'ABCABCABC') returns 'BBB'
- # getNthSubkeysLetter(3, 3, 'ABCABCABC') returns 'CCC'
- # getNthSubkeysLetter(1, 5, 'ABCDEFGHI') returns 'AF'
+ # E.g. getNthSubkeysLetters(1, 3, 'ABCABCABC') returns 'AAA'
+ # getNthSubkeysLetters(2, 3, 'ABCABCABC') returns 'BBB'
+ # getNthSubkeysLetters(3, 3, 'ABCABCABC') returns 'CCC'
+ # getNthSubkeysLetters(1, 5, 'ABCDEFGHI') returns 'AF'
# Use a "regular expression" remove non-letters from the message.
message = NONLETTERS_PATTERN.sub('', message)
@@ -159,7 +159,7 @@ def attemptHackWithKeyLength(ciphertext, mostLikelyKeyLength):
# These inner lists are the freqScores lists.
allFreqScores = []
for nth in range(1, mostLikelyKeyLength + 1):
- nthLetters = getNthSubkeysLetter(nth, mostLikelyKeyLength, ciphertextUp)
+ nthLetters = getNthSubkeysLetters(nth, mostLikelyKeyLength, ciphertextUp)
# freqScores is a list of tuples like:
# [(<letter>, <Eng. Freq. match score>), ... ]
@@ -238,7 +238,7 @@ def hackVigenere(ciphertext):
break
# If none of the key lengths we found using Kasiski Examination
- # worked, start brute forcing through key lengths.
+ # worked, start brute-forcing through key lengths.
if hackedMessage == None:
if not SILENT_MODE:
print('Unable to hack message with likely key length(s). Brute forcing key length...')
Please sign in to comment.
Something went wrong with that request. Please try again.