59.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from itertools import product,cycle
  2. def loadWords():
  3. """
  4. Returns a list of valid words. Words are strings of lowercase letters.
  5. Depending on the size of the word list, this function may
  6. take a while to finish.
  7. """
  8. print("Loading word list from file...")
  9. inFile = open("59_words.txt", 'r')
  10. wordList = inFile.read().split()
  11. print(" ", len(wordList), "words loaded.")
  12. return wordList
  13. wordList = loadWords()
  14. def getCipherList():
  15. """
  16. Returns cipher in encrypted list.
  17. """
  18. return open("cipher1.txt", "r").read().strip('\n').split(",")
  19. def isWord(wordList, word):
  20. """
  21. Determines if word is a valid word.
  22. wordList: list of words in the dictionary.
  23. word: a possible word.
  24. returns True if word is in wordList.
  25. Example:
  26. >>> isWord(wordList, 'bat') returns
  27. True
  28. >>> isWord(wordList, 'asdf') returns
  29. False
  30. """
  31. word = word.lower()
  32. word = word.strip(" !@#$%^&*()-_+={}[]|\\:;'<>?,./\"")
  33. return word in wordList
  34. def numWords(decryptedText):
  35. """ Returns the number of valid words there are in given text """
  36. decryptedList = decryptedText.split()
  37. wordCount = 0
  38. for word in decryptedList:
  39. if isWord(wordList, word):
  40. wordCount += 1
  41. return wordCount
  42. def ascii(cipherList):
  43. """ Takes list of ASCII codes as input, returns concatenated string """
  44. decryptedList = []
  45. for char in cipherList:
  46. decryptedList.append(chr(int(char)))
  47. return "".join(map(chr, list(map(int, cipherList))))
  48. def decrypt(key):
  49. """ Decrypts story using given key using an XOR cipher """
  50. data = ascii(getCipherList())
  51. return "".join(chr(ord(x) ^ ord(y)) for (x,y) in zip(data, cycle(key)))
  52. def asciisum(text):
  53. """ Returns the sum of ASCII codes in a given string """
  54. text = list(text)
  55. text = list(map(ord, text))
  56. return sum(text)
  57. def main():
  58. """
  59. Main wrapper function.
  60. Generates all possible keys, then iterates through them to find the one that
  61. decrypts the original ciphertext into the maximum number of English words.
  62. The function returns the sum of the ASCII codes of the resulting decrypted
  63. text.
  64. """
  65. lowercase = list(map(chr, list(range(97, 123))))
  66. # Generate a list of possible keys
  67. keylist = []
  68. for key in product(lowercase, repeat=3):
  69. keylist.append("".join(key))
  70. currentNumWords = 0
  71. maxWords = 0
  72. bestKey = ""
  73. for key in keylist:
  74. currentNumWords = numWords(decrypt(key))
  75. if currentNumWords > maxWords:
  76. maxWords = currentNumWords
  77. bestKey = key
  78. return asciisum(decrypt(bestKey))
  79. print(main())