Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Changes made while making unit tests.

  • Loading branch information...
commit d95e7daa7c0ce27df94ca911dc4890f7d3e1c9bb 1 parent e280220
@asweigart authored
View
2  affineBreaker.py
@@ -14,7 +14,7 @@ def main():
# The plaintext is displayed on the screen. For the convenience of
# the user, we copy the text of the code to the clipboard.
print('Copying broken ciphertext to clipboard:')
- print(brokenCiphertext[:1000])
+ print(brokenCiphertext)
pyperclip.copy(brokenCiphertext)
else:
print('Failed to break encryption.')
View
1  affineCipher.py
@@ -46,6 +46,7 @@ def encryptMessage(keyA, keyB, message):
sys.exit('The affine cipher becomes incredibly weak when keyA is set to 1. Choose a different key.')
if keyB == 0:
sys.exit('The affine cipher becomes incredibly weak when keyB is set to 0. Choose a different key.')
+
if gcd(keyA, len(LETTERS)) != 1:
sys.exit('The key (%s) and the size of the alphabet (%s) are not relatively prime. Choose a different key.' % (keyA, len(LETTERS)))
View
140 codebreaker_unit_tests.py
@@ -20,6 +20,8 @@
# Be sure to download the pylint.conf config file and have it in the same folderas codebreaker_unit_tests.py
+FOX_MESSAGE = "The quick brown fox jumped over the yellow lazy dog.".upper()
+
def checkForText(filename, text):
fp = open(filename)
content = fp.read()
@@ -88,8 +90,8 @@ def test_simpleSubDictionaryBreakerPy(self):
def test_nullCipherPy(self):
self.runPylintOnFile('nullCipher.py')
- #def test_nullBreakerPy(self):
- # self.runPylintOnFile('nullBreaker.py')
+ def test_nullBreakerPy(self):
+ self.runPylintOnFile('nullBreaker.py')
def test_vigenereCipherPy(self):
self.runPylintOnFile('vigenereCipher.py')
@@ -112,6 +114,8 @@ def test_makeRsaKeysPy(self):
def test_rsaCipherPy(self):
self.runPylintOnFile('rsaCipher.py')
+ def test_pyperclipPy(self):
+ self.runPylintOnFile('pyperclip.py')
class CodeBreakerUnitTests(unittest.TestCase):
@@ -301,12 +305,140 @@ def test_affineCipherProgram(self):
self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+ def test_affineCipherModule(self):
+ import affineCipher
+
+ encrypted = affineCipher.encryptMessage(5, 23, FOX_MESSAGE)
+ decrypted = affineCipher.decryptMessage(5, 23, encrypted)
+
+ self.assertEqual(FOX_MESSAGE, decrypted)
+ self.assertEqual(encrypted, 'OGR ZTLHV CEPDK WPI QTFURM PYRE OGR NRAAPD AXSN MPB.')
+
+ # Test with bad keys:
+ self.assertRaises(SystemExit, affineCipher.encryptMessage, 1, 23, FOX_MESSAGE)
+ self.assertRaises(SystemExit, affineCipher.encryptMessage, 5, 0, FOX_MESSAGE)
+ self.assertRaises(SystemExit, affineCipher.encryptMessage, 26, 23, FOX_MESSAGE)
+ self.assertRaises(SystemExit, affineCipher.encryptMessage, 26, 23, FOX_MESSAGE)
+
+ def test_affineBreakerProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe affineBreaker.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate('D\n'.encode('ascii'))[0].decode('ascii')
+
+ expectedClipboard = 'A COMPUTER WOULD DESERVE TO BE CALLED INTELLIGENT IF IT COULD DECEIVE A HUMAN INTO BELIEVING THAT IT WAS HUMAN. -ALAN TURING'
+
+ self.assertEqual(procOut, 'Encrypted text:\nH RZPEDYBO NZDKW WBTBOIB YZ MB RHKKBW VUYBKKVLBUY VG VY RZDKW WBRBVIB H QDPHU VUYZ MBKVBIVUL YQHY VY NHT QDPHU. -HKHU YDOVUL\nFull encrypted text copied to clipboard.\n')
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+
+ def test_simpleSubCipherProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe simpleSubCipher.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate()[0].decode('ascii')
+
+ expectedClipboard = 'SY L NLX SR PYYACAO L YLWJ EISWI UPAR LULSXRJ ISR SXRJSXWJR, IA ESMM RWCTJSXSZA SJ WMPRAMH, LXO TXMARR JIA AQSOAXWA SR PQACEIAMNSXU, IA ESMM CAYTRA JP FAMSAQA SJ. SY, PX JIA PJIAC ILXO, IA SR PYYACAO RPNAJISXU EISWI LYYPCOR L CALRPX YPC LWJSXU SX LWWPCOLXWA JP ISR SXRJSXWJR, IA ESMM LWWABJ SJ AQAX PX JIA RMSUIJARJ AQSOAXWA. JIA PCSUSX PY NHJIR SR AGBMLSXAO SX JISR ELH. -FACJCLXO CTRRAMM'
+
+ expectedOutput = 'The encrypted message is:\nSY L NLX SR PYYACAO L YLWJ EISWI UPAR LULSXRJ ISR SXRJSXWJR, IA ESMM RWCTJSXSZA SJ WMPRAMH, LXO TXMARR JIA AQSOAXWA SR PQACEIAMNSXU, IA ESMM CAYTRA JP FAMSAQA SJ. SY, PX JIA PJIAC ILXO, IA SR PYYACAO RPNAJISXU EISWI LYYPCOR L CALRPX YPC LWJSXU SX LWWPCOLXWA JP ISR SXRJSXWJR, IA ESMM LWWABJ SJ AQAX PX JIA RMSUIJARJ AQSOAXWA. JIA PCSUSX PY NHJIR SR AGBMLSXAO SX JISR ELH. -FACJCLXO CTRRAMM\n\nThis message has been copied to the clipboard.\n'
+
+ self.assertEqual(procOut, expectedOutput)
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+
+ def test_simpleSubCipherModule(self):
+ import simpleSubCipher
+
+ encrypted = simpleSubCipher.encryptMessage('LFWOAYUISVKMNXPBDCRJTQEGHZ', FOX_MESSAGE)
+ decrypted = simpleSubCipher.decryptMessage('LFWOAYUISVKMNXPBDCRJTQEGHZ', encrypted)
+
+ encrypted2 = simpleSubCipher.encryptMessage('XPBDCRJTQEGHZLFWOAYUISVKMN', FOX_MESSAGE)
+
+ self.assertEqual(encrypted, 'JIA DTSWK FCPEX YPG VTNBAO PQAC JIA HAMMPE MLZH OPU.')
+ self.assertEqual(FOX_MESSAGE, decrypted)
+ self.assertNotEqual(encrypted, encrypted2)
+
+
+ def test_simpleSubBreakerProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe simpleSubBreaker.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate()[0].decode('ascii')
+
+ expectedOutput = 'Breaking...\n(Press Ctrl-C or Ctrl-D to quit at any time.)\nDone.\n\nMapping:\n A B C D E F G H I J K L M N O P Q R S T U V W X Y Z\n = = = = = = = = = = = = = = = = = = = = = = = = = =\n E B R K B B B H T A L M D O V S I U G C N F Z \n W W P Q K \n P X P \n Y W \n P X \n W Y \n \n\nOriginal ciphertext:\nSY L NLX SR PYYACAO L YLWJ EISWI UPAR LULSXRJ ISR SXRJSXWJR, IA ESMM RWCTJSXSZA SJ WMPRAMH, LXO TXMARR JIA AQSOAXWA SR PQACEIAMNSXU, IA ESMM CAYTRA JP FAMSAQA SJ. SY, PX JIA PJIAC ILXO, IA SR PYYACAO RPNAJISXU EISWI LYYPCOR L CALRPX YPC LWJSXU SX LWWPCOLXWA JP ISR SXRJSXWJR, IA ESMM LWWABJ SJ AQAX PX JIA RMSUIJARJ AQSOAXWA. JIA PCSUSX PY NHJIR SR AGBMLSXAO SX JISR ELH. -FACJCLXO CTRRAMM\n\nBroken ciphertext:\nIF A MAN IS OFFERED A FACT _HICH GOES AGAINST HIS INSTINCTS, HE _ILL SCRUTINIZE IT CLOSEL_, AND UNLESS THE EVIDENCE IS OVER_HELMING, HE _ILL REFUSE TO _ELIEVE IT. IF, ON THE OTHER HAND, HE IS OFFERED SOMETHING _HICH AFFORDS A REASON FOR ACTING IN ACCORDANCE TO HIS INSTINCTS, HE _ILL ACCE_T IT EVEN ON THE SLIGHTEST EVIDENCE. THE ORIGIN OF M_THS IS E__LAINED IN THIS _A_. -_ERTRAND RUSSELL\n\n'
+
+ self.assertEqual(procOut, expectedOutput)
+
+
+ def test_simpleSubKeywordProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe simpleSubKeyword.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate()[0].decode('ascii')
+
+ expectedOutput = 'The key used is:\nALPHNUMERICBDFGJKOQSTVWXYZ\nThe encrypted message is:\nYGTO PGVNO RQ LBGWF.\n\nThis message has been copied to the clipboard.\n'
+ expectedClipboard = """YGTO PGVNO RQ LBGWF."""
+
+ self.assertEqual(procOut, expectedOutput)
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+ def test_simpleSubKeywordModule(self):
+ import simpleSubKeyword
+
+ encrypted = simpleSubKeyword.encryptMessage('hello', FOX_MESSAGE)
+ decrypted = simpleSubKeyword.decryptMessage('hello', encrypted)
+ encrypted2= simpleSubKeyword.encryptMessage('howdy', FOX_MESSAGE)
+
+ self.assertEqual(FOX_MESSAGE, decrypted)
+ self.assertNotEqual(encrypted, encrypted2)
+
+ def test_nullBreakerProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe nullBreaker.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate('D\n'.encode('ascii'))[0].decode('ascii')
+
+ expectedClipboard = 'When I use a word, it means just what I choose it to mean -- neither more nor less.'
+
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+ def test_simpleSubDictionaryBreakerProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe simpleSubDictionaryBreaker.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate('D\n'.encode('ascii'))[0].decode('ascii')
+
+ expectedClipboard = 'CONFIDANTE: ONE ENTRUSTED BY A WITH THE SECRETS OF B CONFIDED TO HERSELF BY C. -AMBROSE BIERCE'
+
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+ def test_vigenereCipherProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe vigenereCipher.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate()[0].decode('ascii')
+
+ expectedOutput = 'Encrypted message:\nADIZ AVTZQECI TMZUBB WSA M PMILQEV HALPQAVTAKUOI, LGOUQDAF, KDMKTSVMZTSL, IZR XOEXGHZR KKUSITAAF. VZ WSA TWBHDG UBALMMZHDAD QZ HCE VMHSGOHUQBO OX KAAKULMD GXIWVOS, KRGDURDNY I RCMMSTUGVTAWZ CA TZM OCICWXFG JF "STSCMILPY" OID "UWYDPTSBUCI" WABT HCE LCDWIG EIOVDNW. BGFDNY QE KDDWTK QJNKQPSMEV BA PZ TZM ROOHWZ AT XOEXGHZR KKUSICW IZR VRLQRWXIST UBOEDTUUZNUM. PIMIFO ICMLV EMF DI, LCDWIG OWDYZD XWD HCE YWHSMNEMZH XOVM MBY CQXTSM SUPACG (GUKE) OO BDMFQCLWG BOMK, TZUHVIF\'A OCYETZQOFIFO OSITJM. RCM A LQYS CE OIE VZAV WR VPT 8, LPQ GZCLQAB MEKXABNITTQ TJR YMDAVN FIHOG CJGBHVNSTKGDS. ZM PSQIKMP O IUEJQF JF LMOVIIICQG AOJ JDSVKAVS UZREIZ QDPZMDG, DNUTGRDNY BTS HELPAR JF LPQ PJMTM, MB ZLWKFFJMWKTOIIUIX AVCZQZS OHSB OCPLV NUBY SWBFWIGK NAF OHW MZWBMS UMQCIFM. MTOEJ BTS RAJ PQ KJRCMP OO TZM ZOOIGVMZ KHQAUQVL DINCMALWDM, RHWZQ VZ CJMMHZD GVQ CA TZM RWMSL LQGDGFA RCM A KBAFZD-HZAUMAE KAAKULMD, HCE SKQ. WI 1948 TMZUBB JGQZSY MSF ZSRMSV\'E QJMHCFWIG DINCMALWDM VT EIZQCEKBQF PNADQFNILG, IVZRW PQ ONSAAFSY IF BTS YENMXCKMWVF CA TZM YOICZMEHZR UWYDPTWZE OID TMOOHE AVFSMEKBQR DN EIFVZMSBUQVL TQAZJGQ. PQ KMOLM M DVPWZ AB OHW KTSHIUIX PVSAA AT HOJXTCBEFMEWN, AFL BFZDAKFSY OKKUZGALQZU XHWUUQVL JMMQOIGVE GPCZ IE HCE TMXCPSGD-LVVBGBUBNKQ ZQOXTAWZ, KCIUP ISME XQDGO OTAQFQEV QZ HCE 1960K. BGFDNY\'A TCHOKMJIVLABK FZSMTFSY IF I OFDMAVMZ KRGAQQPTAWZ WI 1952, WZMZ VJMGAQLPAD IOHN WWZQ GOIDT UZGEYIX WI TZM GBDTWL WWIGVWY. VZ AUKQDOEV BDSVTEMZH RILP RSHADM TCMMGVQG (XHWUUQVL UIEHMALQAB) VS SV MZOEJVMHDVW BA DMIKWZ. HPRAVS RDEV QZ 1954, XPSL WHSM TOW ISZKK JQTJRW PUG 42ID TQDHCDSG, RFJM UGMBDDW XAWNOFQZU. VN AVCIZSL LQHZREQZSY TZIF VDS VMMHC WSA EIDCALQ; VDS EWFVZR SVP GJMW WFVZRK JQZDENMP VDS VMMHC WSA MQXIVMZHVL. GV 10 ESKTWUNSM 2009, FGTXCRIFO MB DNLMDBZT UIYDVIYV, NFDTAAT DMIEM YWIIKBQF BOJLAB WRGEZ AVDW IZ CAFAKUOG PMJXWX AHWXCBY GV NSCADN AT OHW JDWOIKP SCQEJVYSIT XWD "HCE SXBOGLAVS KVY ZM ION TJMMHZD." SA AT HAQ 2012 I BFDVSBQ AZMTMD\'G WIDT ION BWNAFZ TZM TCPSW WR ZJRVA IVDCZ EAIGD YZMBO TMZUBB A KBMHPTGZK DVRVWZ WA EFIOHZD.\n\nThe message has been copied to the clipboard.\n'
+ expectedClipboard = 'ADIZ AVTZQECI TMZUBB WSA M PMILQEV HALPQAVTAKUOI, LGOUQDAF, KDMKTSVMZTSL, IZR XOEXGHZR KKUSITAAF. VZ WSA TWBHDG UBALMMZHDAD QZ HCE VMHSGOHUQBO OX KAAKULMD GXIWVOS, KRGDURDNY I RCMMSTUGVTAWZ CA TZM OCICWXFG JF "STSCMILPY" OID "UWYDPTSBUCI" WABT HCE LCDWIG EIOVDNW. BGFDNY QE KDDWTK QJNKQPSMEV BA PZ TZM ROOHWZ AT XOEXGHZR KKUSICW IZR VRLQRWXIST UBOEDTUUZNUM. PIMIFO ICMLV EMF DI, LCDWIG OWDYZD XWD HCE YWHSMNEMZH XOVM MBY CQXTSM SUPACG (GUKE) OO BDMFQCLWG BOMK, TZUHVIF\'A OCYETZQOFIFO OSITJM. RCM A LQYS CE OIE VZAV WR VPT 8, LPQ GZCLQAB MEKXABNITTQ TJR YMDAVN FIHOG CJGBHVNSTKGDS. ZM PSQIKMP O IUEJQF JF LMOVIIICQG AOJ JDSVKAVS UZREIZ QDPZMDG, DNUTGRDNY BTS HELPAR JF LPQ PJMTM, MB ZLWKFFJMWKTOIIUIX AVCZQZS OHSB OCPLV NUBY SWBFWIGK NAF OHW MZWBMS UMQCIFM. MTOEJ BTS RAJ PQ KJRCMP OO TZM ZOOIGVMZ KHQAUQVL DINCMALWDM, RHWZQ VZ CJMMHZD GVQ CA TZM RWMSL LQGDGFA RCM A KBAFZD-HZAUMAE KAAKULMD, HCE SKQ. WI 1948 TMZUBB JGQZSY MSF ZSRMSV\'E QJMHCFWIG DINCMALWDM VT EIZQCEKBQF PNADQFNILG, IVZRW PQ ONSAAFSY IF BTS YENMXCKMWVF CA TZM YOICZMEHZR UWYDPTWZE OID TMOOHE AVFSMEKBQR DN EIFVZMSBUQVL TQAZJGQ. PQ KMOLM M DVPWZ AB OHW KTSHIUIX PVSAA AT HOJXTCBEFMEWN, AFL BFZDAKFSY OKKUZGALQZU XHWUUQVL JMMQOIGVE GPCZ IE HCE TMXCPSGD-LVVBGBUBNKQ ZQOXTAWZ, KCIUP ISME XQDGO OTAQFQEV QZ HCE 1960K. BGFDNY\'A TCHOKMJIVLABK FZSMTFSY IF I OFDMAVMZ KRGAQQPTAWZ WI 1952, WZMZ VJMGAQLPAD IOHN WWZQ GOIDT UZGEYIX WI TZM GBDTWL WWIGVWY. VZ AUKQDOEV BDSVTEMZH RILP RSHADM TCMMGVQG (XHWUUQVL UIEHMALQAB) VS SV MZOEJVMHDVW BA DMIKWZ. HPRAVS RDEV QZ 1954, XPSL WHSM TOW ISZKK JQTJRW PUG 42ID TQDHCDSG, RFJM UGMBDDW XAWNOFQZU. VN AVCIZSL LQHZREQZSY TZIF VDS VMMHC WSA EIDCALQ; VDS EWFVZR SVP GJMW WFVZRK JQZDENMP VDS VMMHC WSA MQXIVMZHVL. GV 10 ESKTWUNSM 2009, FGTXCRIFO MB DNLMDBZT UIYDVIYV, NFDTAAT DMIEM YWIIKBQF BOJLAB WRGEZ AVDW IZ CAFAKUOG PMJXWX AHWXCBY GV NSCADN AT OHW JDWOIKP SCQEJVYSIT XWD "HCE SXBOGLAVS KVY ZM ION TJMMHZD." SA AT HAQ 2012 I BFDVSBQ AZMTMD\'G WIDT ION BWNAFZ TZM TCPSW WR ZJRVA IVDCZ EAIGD YZMBO TMZUBB A KBMHPTGZK DVRVWZ WA EFIOHZD.'
+
+ self.assertEqual(procOut, expectedOutput)
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+
+ def test_vigenereCipherModule(self):
+ import vigenereCipher
+
+ encrypted = vigenereCipher.encryptMessage('ANTICS', FOX_MESSAGE)
+ decrypted = vigenereCipher.decryptMessage('ANTICS', encrypted)
+
+ encrypted2 = vigenereCipher.encryptMessage('WOOF', FOX_MESSAGE)
+
+ self.assertEqual(FOX_MESSAGE, decrypted)
+ self.assertNotEqual(encrypted, encrypted2)
+
+ def test_vigenereBreakerProgram(self):
+ proc = subprocess.Popen('c:\\python32\\python.exe vigenereBreaker.py', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+ procOut = proc.communicate('D\n'.encode('ascii'))[0].decode('ascii')
+
+ expectedClipboard = """ALAN MATHISON TURING WAS A BRITISH MATHEMATICIAN, LOGICIAN, CRYPTANALYST, AND COMPUTER SCIENTIST. HE WAS HIGHLY INFLUENTIAL IN THE DEVELOPMENT OF COMPUTER SCIENCE, PROVIDING A FORMALISATION OF THE CONCEPTS OF "ALGORITHM" AND "COMPUTATION" WITH THE TURING MACHINE. TURING IS WIDELY CONSIDERED TO BE THE FATHER OF COMPUTER SCIENCE AND ARTIFICIAL INTELLIGENCE. DURING WORLD WAR II, TURING WORKED FOR THE GOVERNMENT CODE AND CYPHER SCHOOL (GCCS) AT BLETCHLEY PARK, BRITAIN'S CODEBREAKING CENTRE. FOR A TIME HE WAS HEAD OF HUT 8, THE SECTION RESPONSIBLE FOR GERMAN NAVAL CRYPTANALYSIS. HE DEVISED A NUMBER OF TECHNIQUES FOR BREAKING GERMAN CIPHERS, INCLUDING THE METHOD OF THE BOMBE, AN ELECTROMECHANICAL MACHINE THAT COULD FIND SETTINGS FOR THE ENIGMA MACHINE. AFTER THE WAR HE WORKED AT THE NATIONAL PHYSICAL LABORATORY, WHERE HE CREATED ONE OF THE FIRST DESIGNS FOR A STORED-PROGRAM COMPUTER, THE ACE. IN 1948 TURING JOINED MAX NEWMAN'S COMPUTING LABORATORY AT MANCHESTER UNIVERSITY, WHERE HE ASSISTED IN THE DEVELOPMENT OF THE MANCHESTER COMPUTERS AND BECAME INTERESTED IN MATHEMATICAL BIOLOGY. HE WROTE A PAPER ON THE CHEMICAL BASIS OF MORPHOGENESIS, AND PREDICTED OSCILLATING CHEMICAL REACTIONS SUCH AS THE BELOUSOV-ZHABOTINSKY REACTION, WHICH WERE FIRST OBSERVED IN THE 1960S. TURING'S HOMOSEXUALITY RESULTED IN A CRIMINAL PROSECUTION IN 1952, WHEN HOMOSEXUAL ACTS WERE STILL ILLEGAL IN THE UNITED KINGDOM. HE ACCEPTED TREATMENT WITH FEMALE HORMONES (CHEMICAL CASTRATION) AS AN ALTERNATIVE TO PRISON. TURING DIED IN 1954, JUST OVER TWO WEEKS BEFORE HIS 42ND BIRTHDAY, FROM CYANIDE POISONING. AN INQUEST DETERMINED THAT HIS DEATH WAS SUICIDE; HIS MOTHER AND SOME OTHERS BELIEVED HIS DEATH WAS ACCIDENTAL. ON 10 SEPTEMBER 2009, FOLLOWING AN INTERNET CAMPAIGN, BRITISH PRIME MINISTER GORDON BROWN MADE AN OFFICIAL PUBLIC APOLOGY ON BEHALF OF THE BRITISH GOVERNMENT FOR "THE APPALLING WAY HE WAS TREATED." AS OF MAY 2012 A PRIVATE MEMBER'S BILL WAS BEFORE THE HOUSE OF LORDS WHICH WOULD GRANT TURING A STATUTORY PARDON IF ENACTED."""
+ expectedOutput = 'Determining most likely key lengths with Kasiski Examination...\nKasiski Examination results say the most likely key lengths are: 3 2 6 4 12 \n\nPossible letters for letter 1 of the key: A L M \nPossible letters for letter 2 of the key: S N O \nPossible letters for letter 3 of the key: V I Z \nAttempting with key: ASV\nAttempting with key: ASI\nAttempting with key: ASZ\nAttempting with key: ANV\nAttempting with key: ANI\nAttempting with key: ANZ\nAttempting with key: AOV\nAttempting with key: AOI\nAttempting with key: AOZ\nAttempting with key: LSV\nAttempting with key: LSI\nAttempting with key: LSZ\nAttempting with key: LNV\nAttempting with key: LNI\nAttempting with key: LNZ\nAttempting with key: LOV\nAttempting with key: LOI\nAttempting with key: LOZ\nAttempting with key: MSV\nAttempting with key: MSI\nAttempting with key: MSZ\nAttempting with key: MNV\nAttempting with key: MNI\nAttempting with key: MNZ\nAttempting with key: MOV\nAttempting with key: MOI\nAttempting with key: MOZ\nPossible letters for letter 1 of the key: O A E \nPossible letters for letter 2 of the key: M S I \nAttempting with key: OM\nAttempting with key: OS\nAttempting with key: OI\nAttempting with key: AM\nAttempting with key: AS\nAttempting with key: AI\nAttempting with key: EM\nAttempting with key: ES\nAttempting with key: EI\nPossible letters for letter 1 of the key: A E O \nPossible letters for letter 2 of the key: S D G \nPossible letters for letter 3 of the key: I V X \nPossible letters for letter 4 of the key: M Z Q \nPossible letters for letter 5 of the key: O B Z \nPossible letters for letter 6 of the key: V I K \nAttempting with key: ASIMOV\n\nPossible encryption break:\nKey ASIMOV: ALAN MATHISON TURING WAS A BRITISH MATHEMATICIAN, LOGICIAN, CRYPTANALYST, AND COMPUTER SCIENTIST. HE WAS HIGHLY INFLUENTIAL IN THE DEVELOPMENT OF COMPUTER SCIENCE, PROVIDING A FORMALISATION OF THE CON\n\nEnter D for done, or just press Enter to continue breaking:\n> Copying broken ciphertext to clipboard:\nALAN MATHISON TURING WAS A BRITISH MATHEMATICIAN, LOGICIAN, CRYPTANALYST, AND COMPUTER SCIENTIST. HE WAS HIGHLY INFLUENTIAL IN THE DEVELOPMENT OF COMPUTER SCIENCE, PROVIDING A FORMALISATION OF THE CONCEPTS OF "ALGORITHM" AND "COMPUTATION" WITH THE TURING MACHINE. TURING IS WIDELY CONSIDERED TO BE THE FATHER OF COMPUTER SCIENCE AND ARTIFICIAL INTELLIGENCE. DURING WORLD WAR II, TURING WORKED FOR THE GOVERNMENT CODE AND CYPHER SCHOOL (GCCS) AT BLETCHLEY PARK, BRITAIN\'S CODEBREAKING CENTRE. FOR A TIME HE WAS HEAD OF HUT 8, THE SECTION RESPONSIBLE FOR GERMAN NAVAL CRYPTANALYSIS. HE DEVISED A NUMBER OF TECHNIQUES FOR BREAKING GERMAN CIPHERS, INCLUDING THE METHOD OF THE BOMBE, AN ELECTROMECHANICAL MACHINE THAT COULD FIND SETTINGS FOR THE ENIGMA MACHINE. AFTER THE WAR HE WORKED AT THE NATIONAL PHYSICAL LABORATORY, WHERE HE CREATED ONE OF THE FIRST DESIGNS FOR A STORED-PROGRAM COMPUTER, THE ACE. IN 1948 TURING JOINED MAX NEWMAN\'S COMPUTING LABORATORY AT MANCHESTER UNIVERSITY, WHERE HE ASSISTED IN THE DEVELOPMENT OF THE MANCHESTER COMPUTERS AND BECAME INTERESTED IN MATHEMATICAL BIOLOGY. HE WROTE A PAPER ON THE CHEMICAL BASIS OF MORPHOGENESIS, AND PREDICTED OSCILLATING CHEMICAL REACTIONS SUCH AS THE BELOUSOV-ZHABOTINSKY REACTION, WHICH WERE FIRST OBSERVED IN THE 1960S. TURING\'S HOMOSEXUALITY RESULTED IN A CRIMINAL PROSECUTION IN 1952, WHEN HOMOSEXUAL ACTS WERE STILL ILLEGAL IN THE UNITED KINGDOM. HE ACCEPTED TREATMENT WITH FEMALE HORMONES (CHEMICAL CASTRATION) AS AN ALTERNATIVE TO PRISON. TURING DIED IN 1954, JUST OVER TWO WEEKS BEFORE HIS 42ND BIRTHDAY, FROM CYANIDE POISONING. AN INQUEST DETERMINED THAT HIS DEATH WAS SUICIDE; HIS MOTHER AND SOME OTHERS BELIEVED HIS DEATH WAS ACCIDENTAL. ON 10 SEPTEMBER 2009, FOLLOWING AN INTERNET CAMPAIGN, BRITISH PRIME MINISTER GORDON BROWN MADE AN OFFICIAL PUBLIC APOLOGY ON BEHALF OF THE BRITISH GOVERNMENT FOR "THE APPALLING WAY HE WAS TREATED." AS OF MAY 2012 A PRIVATE MEMBER\'S BILL WAS BEFORE THE HOUSE OF LORDS WHICH WOULD GRANT TURING A STATUTORY PARDON IF ENACTED.\n'
+
+ self.assertEqual(pyperclip.paste().decode('ascii'), expectedClipboard)
+ self.assertEqual(procOut, expectedOutput)
+
+
+
if __name__ == '__main__':
- TEST_ALL = True #False
+ TEST_ALL = False
if not TEST_ALL:
customSuite = unittest.TestSuite()
- customSuite.addTest(CodeBreakerUnitTests('test_affineCipherProgram'))
+ customSuite.addTest(CodeBreakerUnitTests('test_vigenereBreakerProgram'))
unittest.TextTestRunner().run(customSuite)
elif TEST_ALL:
unittest.main()
View
41 nullBreaker.py
@@ -1,7 +1,7 @@
# Null Cipher Breaker
# http://inventwithpython.com/codebreaker (BSD Licensed)
-import nullCipher, pyperclip, detectEnglish
+import nullCipher, pyperclip, detectEnglish, itertools, sys
# There are two settings our breaking program needs to limit the range of the possible keys it checks.
# MAX_KEY_NUMBER is the range of numbers it checks for each number in the key. A MAX_KEY_NUMBER value of 9 means it will check the numbers 0 through 9.
@@ -10,8 +10,10 @@
MAX_KEY_NUMBER = 9
MAX_KEY_LENGTH = 5
-myMessage = 'kWhhbe#n n>IP uTksEe b<aZ wXCo(rdq7,( iActy moveeanggsU jCku2stmT dwhlvaPt FZIx czyhtoo(&sxe SUi6t Ylt#o 3kmCeaU5nb -rR-b nbLegitOTh6eroN Jmogzr2e Lgnpor/0 GleOjs.s.'
- #W h e n I u s e a w o rd , i t m eans just what I choose it to mean -- neither more nor less.
+SILENT_MODE = False
+
+myMessage = """y\ZWh,De,. n #{ItZ9 uL<sl6!e 2&a"\B w{Eo;l#rdvK,9\s i.Xt?WC mQ-ef>yanpushOz j9lu_H4stsd .Bawhmua_ogt <`I#w$ ctoh({'oo={sINUe 84i%G3t NLt2#Wo 7Zm*<^eacUnuG6 -=g-f:! nxQe$Qmit&Ah0#ner:O Gt!moc;rXGUe q/nKrgor"\ 9 \lecBs|10s.9i"""
+# Wh e n I u s e a w o rd , i t m e an s j u st wh a t I c h oo s e i t t o m ea n - - n e it h er mo r e n or le s s.
def main():
# As a convenience to the user, we will calculate the number of keys that the current MAX_KEY_LENGTH and MAX_KEY_NUMBER settings will cause the breaker program to go through.
@@ -46,31 +48,30 @@ def main():
def breakNull(ciphertext):
# The program needs to try keys of length 1 (such as '5'), of length 2 (such as '5 5'), and so on up to length MAX_KEY_LENGTH.
# This is because the key '1 0' will decrypt differently than '1 0 0'.
- for trialKeyLength in range(1, MAX_KEY_LENGTH + 1):
- # We will be using the "list of int values" for of keys. The string form like '4 2 3' that we use in the original encryption program is used just because it makes it easier to type for the user.
- # We use list replication (multiplying a list value by an int value) to get the starting key.
- trialKey = [0] * trialKeyLength
-
- trialKey = getNextKey(trialKey)
-
- while trialKey != [0] * trialKeyLength:
- decryptedText = nullCipher.decryptMessage(ciphertext, trialKey)
- percentEnglish = round(detectEnglish.getEnglishCount(decryptedText) * 100, 2)
- if percentEnglish > 0:
- print('Key %s decrypts to %s%% English.' % (trialKey, percentEnglish))
- if percentEnglish >= 25:
+ for keyLength in range(1, MAX_KEY_LENGTH + 1):
+ for keyParts in itertools.product(range(MAX_KEY_NUMBER + 1), repeat=keyLength):
+ key = []
+ for digit in keyParts:
+ key.append(str(digit))
+ key = ''.join(key)
+
+ decryptedText = nullCipher.decryptMessage(key, ciphertext)
+
+ if not SILENT_MODE:
+ print('Key %s: %s' % (key, decryptedText[:40]))
+
+ if detectEnglish.isEnglish(decryptedText):
print()
print('Possible encryption break:')
- print('Key ' + str(trialKey) + ': ' + decryptedText[:100])
+ print('Key: %s' % (key))
+ print('Decrypted message: ' + decryptedText[:200])
print()
print('Enter D for done, or just press Enter to continue breaking:')
response = input('> ')
if response.strip().upper().startswith('D'):
return decryptedText
- trialKey = getNextKey(trialKey)
- print('Failed to break encryption.')
- return None
+ return None # failed to break encryption
if __name__ == '__main__':
View
4 nullCipher.py
@@ -22,7 +22,7 @@ def main():
pyperclip.copy(translated)
-def encryptMessage(message, key):
+def encryptMessage(key, message):
# The expression int(key[keyIndex]) will be used to decide how many
# nulls should be inserted. For example, if key is the value '102' and
# keyIndex is 0, then 1 null character will be inserted into the
@@ -56,7 +56,7 @@ def encryptMessage(message, key):
return ciphertext
-def decryptMessage(message, key):
+def decryptMessage(key, message):
# The value inside messageIndex will refer to the index we are
# currently looking at in message.
messageIndex = 0
View
41 pyperclip.py
@@ -1,37 +1,5 @@
# Pyperclip v1.4
-
-
-"""TODO - need to update to fall back on TK
-
-from Tkinter import Tk
-r = Tk()
-r.withdraw()
-r.clipboard_clear()
-r.clipboard_append('i can has clipboardz?')
-print r.clipboard_get()
-r.destroy()
-
-
-Do performance testing on other OSes to see if this approach beats out the others.
-"""
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# A cross-platform clipboard module for Python. (only handles plain text for now)
# By Al Sweigart al@coffeeghost.net
@@ -75,7 +43,7 @@
# 1.2 Use the platform module to help determine OS.
# 1.3 Changed ctypes.windll.user32.OpenClipboard(None) to ctypes.windll.user32.OpenClipboard(0), after some people ran into some TypeError
-import platform, os
+import platform, os, sys
def winGetClipboard():
ctypes.windll.user32.OpenClipboard(0)
@@ -103,7 +71,7 @@ def winSetClipboard(text):
# works on Python 3 (bytes() requires an encoding)
ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pchData), bytes(text, 'ascii'))
ctypes.windll.kernel32.GlobalUnlock(hCd)
- ctypes.windll.user32.SetClipboardData(1,hCd)
+ ctypes.windll.user32.SetClipboardData(1, hCd)
ctypes.windll.user32.CloseClipboard()
def macSetClipboard(text):
@@ -121,6 +89,7 @@ def gtkGetClipboard():
return gtk.Clipboard().wait_for_text()
def gtkSetClipboard(text):
+ global cb
cb = gtk.Clipboard()
cb.set_text(text)
cb.store()
@@ -175,11 +144,11 @@ def xselGetClipboard():
import gtk
getcb = gtkGetClipboard
setcb = gtkSetClipboard
- except:
+ except Exception:
try:
import PyQt4.QtCore
import PyQt4.QtGui
- app = QApplication([])
+ app = PyQt4.QApplication([])
cb = PyQt4.QtGui.QApplication.clipboard()
getcb = qtGetClipboard
setcb = qtSetClipboard
View
1  simpleSubCipher.py
@@ -36,6 +36,7 @@ def checkValidKey(key):
def translateMessage(key, message, mode):
translated = ''
+ message = message.upper()
SET_A = LETTERS
SET_B = key
View
5 simpleSubKeyword.py
@@ -4,7 +4,7 @@
import pyperclip, simpleSubCipher
def main():
- myMessage = r"""This is my secret message."""
+ myMessage = r"""Your cover is blown."""
myKey = 'alphanumeric'
myMode = 'encrypt' # set to 'encrypt' or 'decrypt'
@@ -38,7 +38,8 @@ def decryptMessage(key, message):
def makeSimpleSubKey(keyword):
# create the key from the keyword
newKey = ''
- keyAlphabet = list(' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~')
+ keyword = keyword.upper()
+ keyAlphabet = list(simpleSubCipher.LETTERS)
for i in range(len(keyword)):
if keyword[i] not in newKey:
newKey += keyword[i]
View
40 vigenereBreaker.py
@@ -134,26 +134,31 @@ def getNthLetter(nth, keyLength, message):
def breakVigenere(ciphertext):
# First, we need to do Kasiski Examination to figure out what the length of the ciphertext's encryption key is.
- print('Determining most likely key lengths with Kasiski Examination...')
+ if not SILENT_MODE:
+ print('Determining most likely key lengths with Kasiski Examination...')
+
allLikelyKeyLengths = kasiskiExamination(ciphertext)
- print('Kasiski Examination results say the most likely key lengths are: ', end='')
- for keyLength in allLikelyKeyLengths:
- print('%s ' % (keyLength), end='')
- print()
- print()
+ if not SILENT_MODE:
+ print('Kasiski Examination results say the most likely key lengths are: ', end='')
+ for keyLength in allLikelyKeyLengths:
+ print('%s ' % (keyLength), end='')
+ print()
+ print()
for keyLength in allLikelyKeyLengths:
- print('Attempting break with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
+ #print('Attempting break with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
brokenCiphertext = attemptBreakWithKeyLength(ciphertext, keyLength)
if brokenCiphertext != None:
break
# If none of the key lengths we found using Kasiski Examination worked, start brute forcing through key lengths.
if brokenCiphertext == None:
- print('Unable to break message with likely key length(s). Brute forcing key length...')
+ if not SILENT_MODE:
+ print('Unable to break message with likely key length(s). Brute forcing key length...')
for keyLength in range(1, MAX_KEY_LENGTH + 1):
if keyLength not in allLikelyKeyLengths: # don't re-check key lengths we've already tried from Kasiski Examination
- print('Attempting break with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
+ if not SILENT_MODE:
+ print('Attempting break with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
brokenCiphertext = attemptBreakWithKeyLength(ciphertext, keyLength)
if brokenCiphertext != None:
break
@@ -200,7 +205,7 @@ def attemptBreakWithKeyLength(ciphertext, mostLikelyKeyLength):
# match. See the englishFreqMatch() comments in freqFinder).
freqScores = []
for possibleKey in LETTERS:
- translated = vigenereCipher.decryptMessage(nthLetters, possibleKey)
+ translated = vigenereCipher.decryptMessage(possibleKey, nthLetters)
freqScores.append((possibleKey, freqFinder.englishFreqMatch(translated)))
# Each value in freqScores is a tuple (<letter>, <match score>). Since
@@ -210,12 +215,13 @@ def attemptBreakWithKeyLength(ciphertext, mostLikelyKeyLength):
allFreqScores.append(freqScores[:NUM_MOST_FREQ_LETTERS])
- for i in range(len(allFreqScores)):
- # use i+1, because otherwise the "first" letter is called the "0th" letter
- print('Possible letters for letter %s of the key: ' % (i + 1), end='')
- for freqScore in allFreqScores[i]:
- print('%s ' % freqScore[0], end='')
- print()
+ if not SILENT_MODE:
+ for i in range(len(allFreqScores)):
+ # use i+1, because otherwise the "first" letter is called the "0th" letter
+ print('Possible letters for letter %s of the key: ' % (i + 1), end='')
+ for freqScore in allFreqScores[i]:
+ print('%s ' % freqScore[0], end='')
+ print()
# Try every combination of the most likely letters for each position
# in the key.
@@ -228,7 +234,7 @@ def attemptBreakWithKeyLength(ciphertext, mostLikelyKeyLength):
if not SILENT_MODE:
print('Attempting with key: %s' % (possibleKey))
- decryptedText = vigenereCipher.decryptMessage(ciphertext, possibleKey)
+ decryptedText = vigenereCipher.decryptMessage(possibleKey, ciphertext)
if freqFinder.englishTrigramMatch(decryptedText):
if detectEnglish.isEnglish(decryptedText):
View
14 vigenereCipher.py
@@ -14,9 +14,9 @@ def main():
key = key.upper()
if mode == 'encrypt':
- translated = translateMessage(message, key, 'encrypt')
+ translated = encryptMessage(key, message)
elif mode == 'decrypt':
- translated = translateMessage(message, key, 'decrypt')
+ translated = decryptMessage(key, message)
print('%sed message:' % (mode.title()))
print(translated)
@@ -25,15 +25,15 @@ def main():
print('The message has been copied to the clipboard.')
-def encryptMessage(message, key):
- return translateMessage(message, key, 'encrypt')
+def encryptMessage(key, message):
+ return translateMessage(key, message, 'encrypt')
-def decryptMessage(message, key):
- return translateMessage(message, key, 'decrypt')
+def decryptMessage(key, message):
+ return translateMessage(key, message, 'decrypt')
-def translateMessage(message, key, mode):
+def translateMessage(key, message, mode):
translated = [] # stores the encrypted/decrypted message string
keyIndex = 0
Please sign in to comment.
Something went wrong with that request. Please try again.