From 6009f35c1442c11bba654adefaa01328cb2b94fa Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 29 Apr 2020 00:41:48 +0100 Subject: [PATCH] Fixed some Pytest stuff --- .idea/.gitignore | 8 ++++ .idea/Ciphey.iml | 14 ++++++ .../inspectionProfiles/profiles_settings.xml | 6 +++ .idea/misc.xml | 7 +++ .idea/modules.xml | 8 ++++ .idea/other.xml | 6 +++ .idea/vcs.xml | 6 +++ MANIFEST.in | 2 + README.MD | 4 ++ app/Decryptor/Encoding/__init__.py | 0 app/Decryptor/Encoding/encodingParent.py | 10 ++--- app/Decryptor/__init__.py | 0 app/Decryptor/basicEncryption/basic_parent.py | 27 +++++------ app/Decryptor/basicEncryption/caesar.py | 11 ++--- app/Decryptor/basicEncryption/reverse.py | 10 +++-- app/Decryptor/basicEncryption/viginere.py | 4 +- app/Tests/test_Encoding.py | 41 +++++++++-------- app/Tests/test_basic_parent.py | 24 +++++----- app/Tests/test_caesarcipher_basic.py | 36 +++++++++------ app/Tests/test_chi_squared.py | 24 +++++----- app/Tests/test_integration_languagechecker.py | 38 ++++++++-------- app/Tests/test_neural_network.py | 12 ++--- app/__main__.py | 2 +- app/languageCheckerMod/LanguageChecker.py | 11 +++-- app/languageCheckerMod/chisquared.py | 4 +- app/languageCheckerMod/dictionaryChecker.py | 12 ++--- license | 7 +++ logo.png | Bin 0 -> 61807 bytes setup.py | 42 ++++++++++++++++++ 29 files changed, 253 insertions(+), 123 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/Ciphey.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/other.xml create mode 100644 .idea/vcs.xml create mode 100644 MANIFEST.in create mode 100644 app/Decryptor/Encoding/__init__.py create mode 100644 app/Decryptor/__init__.py create mode 100644 license create mode 100644 logo.png create mode 100644 setup.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/Ciphey.iml b/.idea/Ciphey.iml new file mode 100644 index 0000000..b02dcb0 --- /dev/null +++ b/.idea/Ciphey.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f3c49ac --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..bb282bc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..a708ec7 --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..8d44290 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include /appp/languageCheckerMod/* +include README.MD \ No newline at end of file diff --git a/README.MD b/README.MD index eb4b906..27c1812 100644 --- a/README.MD +++ b/README.MD @@ -1,3 +1,7 @@ +![Ciphey][logo.png] +made with python +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +![Ciphey's Tests](https://github.com/brandonskerritt/Ciphey/workflows/Python%20application/badge.svg?branch=master) # What is this? Ciphey is an automated decryption tool. You put in encrypted text, and it outputs the decrypted text. diff --git a/app/Decryptor/Encoding/__init__.py b/app/Decryptor/Encoding/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/Decryptor/Encoding/encodingParent.py b/app/Decryptor/Encoding/encodingParent.py index ba703b7..f632e25 100644 --- a/app/Decryptor/Encoding/encodingParent.py +++ b/app/Decryptor/Encoding/encodingParent.py @@ -1,8 +1,8 @@ -from Decryptor.Encoding.base64 import Base64 -from Decryptor.Encoding.binary import Binary -from Decryptor.Encoding.hexadecimal import Hexadecimal -from Decryptor.Encoding.ascii import Ascii -from Decryptor.Encoding.morsecode import MorseCode +from app.Decryptor.Encoding.base64 import Base64 +from app.Decryptor.Encoding.binary import Binary +from app.Decryptor.Encoding.hexadecimal import Hexadecimal +from app.Decryptor.Encoding.ascii import Ascii +from app.Decryptor.Encoding.morsecode import MorseCode class EncodingParent: def __init__(self, lc): diff --git a/app/Decryptor/__init__.py b/app/Decryptor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/Decryptor/basicEncryption/basic_parent.py b/app/Decryptor/basicEncryption/basic_parent.py index 1dbff1a..3542938 100644 --- a/app/Decryptor/basicEncryption/basic_parent.py +++ b/app/Decryptor/basicEncryption/basic_parent.py @@ -1,8 +1,8 @@ -from Decryptor.basicEncryption.caesar import Caesar -from Decryptor.basicEncryption.reverse import Reverse -from Decryptor.basicEncryption.viginere import Viginere -from Decryptor.basicEncryption.pigLatin import PigLatin -from Decryptor.basicEncryption.transposition import Transposition +import app.Decryptor.basicEncryption.caesar +import app.Decryptor.basicEncryption.reverse +import app.Decryptor.basicEncryption.viginere +import app.Decryptor.basicEncryption.pigLatin + """ So I want to assign the prob distribution to objects so it makes sense to do this? @@ -32,23 +32,22 @@ for key, val in self.prob: list_objs.insert(counter, list_objs.pop(listCounter)) counter = counter + 1 -Eventually we get a sorted list of objs - - +Eventually we get a sorted list of obj """ + class BasicParent: def __init__(self, lc): self.lc = lc - self.caesar = Caesar(self.lc) - self.reverse = Reverse(self.lc) - self.viginere = Viginere(self.lc) - self.pig = PigLatin(self.lc) + self.caesar = app.Decryptor.basicEncryption.caesar.Caesar(self.lc) + self.reverse = app.Decryptor.basicEncryption.reverse.Reverse(self.lc) + self.viginere = app.Decryptor.basicEncryption.viginere.Viginere(self.lc) + self.pig = app.Decryptor.basicEncryption.pigLatin.PigLatin(self.lc) # self.trans = Transposition(self.lc) self.list_of_objects = [self.caesar, self.reverse, self.pig] + def decrypt(self, text): self.text = text - from multiprocessing.dummy import Pool as ThreadPool pool = ThreadPool(4) answers = pool.map(self.callDecrypt, self.list_of_objects) @@ -69,11 +68,13 @@ class BasicParent: if result["IsPlaintext?"]: return result return {"lc": self.lc, "IsPlaintext?": False, "Plaintext": None, "Cipher": None, "Extra Information": None} + def callDecrypt(self, obj): # i only exist to call decrypt return obj.decrypt(self.text) def setProbTable(self, prob): + """I'm still writing this""" self.probabilityDistribution = prob # we get a sorted list of objects :) counter = 0 diff --git a/app/Decryptor/basicEncryption/caesar.py b/app/Decryptor/basicEncryption/caesar.py index d23b1ce..b48bd2a 100644 --- a/app/Decryptor/basicEncryption/caesar.py +++ b/app/Decryptor/basicEncryption/caesar.py @@ -8,16 +8,15 @@ Github: brandonskerritt """ -class Caesar(): +class Caesar: def __init__(self, lc): self.lc = lc + def getName(self): return "Caesar" + def decrypt(self, message): - ''' Simple python program to bruteforce a caesar cipher''' - - ''' Simple python program for the caesar cipher''' - + """ Simple python program to bruteforce a caesar cipher""" # Example string message = message.lower() @@ -49,5 +48,3 @@ class Caesar(): return {"lc": self.lc, "IsPlaintext?": True, "Plaintext": translated, "Cipher": "Caesar", "Extra Information": f"The rotation used is {counter}"} # if none of them match English, return false! return {"lc": self.lc, "IsPlaintext?": False, "Plaintext": None, "Cipher": "Caesar", "Extra Information": None} - - diff --git a/app/Decryptor/basicEncryption/reverse.py b/app/Decryptor/basicEncryption/reverse.py index a3dfeec..434a4ac 100644 --- a/app/Decryptor/basicEncryption/reverse.py +++ b/app/Decryptor/basicEncryption/reverse.py @@ -1,8 +1,11 @@ -import mathsHelper +import app.mathsHelper + + class Reverse: def __init__(self, lc): self.lc = lc - self.mh = mathsHelper.mathsHelper() + self.mh = app.mathsHelper.mathsHelper() + def decrypt(self, message): message = self.mh.stripPuncuation(message) @@ -12,5 +15,6 @@ class Reverse: return {"lc": self.lc, "IsPlaintext?": True, "Plaintext": message, "Cipher": "Reverse", "Extra Information": None} else: return {"lc": self.lc, "IsPlaintext?": False, "Plaintext": None, "Cipher": "Reverse", "Extra Information": None} + def getName(self): - return "Reverse" \ No newline at end of file + return "Reverse" diff --git a/app/Decryptor/basicEncryption/viginere.py b/app/Decryptor/basicEncryption/viginere.py index 4914ba6..fc241f9 100644 --- a/app/Decryptor/basicEncryption/viginere.py +++ b/app/Decryptor/basicEncryption/viginere.py @@ -1,5 +1,5 @@ import itertools, re -from Decryptor.basicEncryption import freqAnalysis +import app.Decryptor.basicEncryption.freqAnalysis class Viginere: def __init__(self, lc): self.LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -173,7 +173,7 @@ class Viginere: freqScores = [] for possibleKey in self.LETTERS: decryptedText = self.decryptMessage(possibleKey, nthLetters) - keyAndFreqMatchTuple = (possibleKey, freqAnalysis.englishFreqMatchScore(decryptedText)) + keyAndFreqMatchTuple = (possibleKey, app.Decryptor.basicEncryption.freqAnalysis.englishFreqMatchScore(decryptedText)) freqScores.append(keyAndFreqMatchTuple) # Sort by match score: freqScores.sort(key=self.getItemAtIndexOne, reverse=True) diff --git a/app/Tests/test_Encoding.py b/app/Tests/test_Encoding.py index af236f0..334a115 100644 --- a/app/Tests/test_Encoding.py +++ b/app/Tests/test_Encoding.py @@ -1,8 +1,13 @@ -import sys -sys.path.append("..") +import sys +# sys.path.append('..') + import unittest -from app.Decryptor.Encoding.encodingParent import EncodingParent -from languageCheckerMod.languageChecker import LanguageChecker +# from app.Decryptor.Encoding.encodingParent import EncodingParent +import app.Decryptor.Encoding.encodingParent +import app.languageCheckerMod.LanguageChecker + +import app.languageCheckerMod.LanguageChecker +#from languageCheckerMod import LanguageChecker # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests # python3 -m unittest discover -s Tests -p test*.py @@ -10,41 +15,41 @@ from languageCheckerMod.languageChecker import LanguageChecker class TestNN(unittest.TestCase): def test_english_yes(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) result = ep.decrypt("eW91ciB0ZXh0") self.assertEqual(result['IsPlaintext?'], True) def test_base64_spaces_yes(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) result = ep.decrypt("SGVsbG8gSSBsaWtlIGRvZ3MgYW5kIGNhdHM=") self.assertEqual(result['IsPlaintext?'], True) def test_binary_spaces_yes(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) result = ep.decrypt("01001000 01100101 01101100 01101100 01101111 00100000 01001001 00100000 01101100 01101001 01101011 01100101 00100000 01100100 01101111 01100111 01110011 00100000 01100001 01101110 01100100 00100000 01100011 01100001 01110100 01110011") self.assertEqual(result['IsPlaintext?'], True) def test_hex_spaces_yes(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) result = ep.decrypt("68 65 6c 6c 6f 20 6f 6c 69 76 69 61 20 69 20 72 65 61 6c 6c 79 20 6c 69 6b 65 20 79 6f 75 72 20 64 6f 67") self.assertEqual(result['IsPlaintext?'], True) def test_hex_spaces_yes(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) a = "68656c6c6f206f 6c 69 76 69 61 20 69 20 72 65 61 6c 6c 79 20 6c 69 6b 65 20 79 6f 75 72 20 64 6f 67" a = a.replace(" ", "") result = ep.decrypt(a) self.assertEqual(result['IsPlaintext?'], True) def test_ascii(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) a = "68 65 6C 6C 6F 20 64 6F 67" result = ep.decrypt(a) self.assertEqual(result['IsPlaintext?'], True) def test_morse(self): - lc = LanguageChecker() - ep = EncodingParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + ep = app.Decryptor.Encoding.encodingParent.EncodingParent(lc) a = ".... . .-.. .-.. --- / -- -.-- / -. .- -- . / .. ... / -... .-. .- -. -.. --- -." result = ep.decrypt(a) self.assertEqual(result['IsPlaintext?'], True) \ No newline at end of file diff --git a/app/Tests/test_basic_parent.py b/app/Tests/test_basic_parent.py index 69e9350..263428f 100644 --- a/app/Tests/test_basic_parent.py +++ b/app/Tests/test_basic_parent.py @@ -1,30 +1,30 @@ -import sys -sys.path.append("..") import unittest -from Decryptor.basicEncryption.basic_parent import BasicParent -from languageCheckerMod.languageChecker import LanguageChecker +import sys +# sys.path.append("..") +import app.Decryptor.basicEncryption.basic_parent +import app.languageCheckerMod.LanguageChecker # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests # python3 -m unittest discover -s Tests -p test*.py class TestBasicParent(unittest.TestCase): def test_basic_parent_caesar_yes(self): - lc = LanguageChecker() - bp = BasicParent(lc) + lc = app.languageCheckerMod.LanguageChecker.languageCheckerMod.LanguageChecker.LanguageChecker() + bp = app.Decryptor.basicEncryption.basic_parent.BasicParent(lc) result = bp.decrypt("uryyb zl sngure uryyb zl zbgure naq v ernyyl qb yvxr n tbbq ratyvfu oernxsnfg") self.assertEqual(result['IsPlaintext?'], True) def test_basic_parent_reverse_yes(self): - lc = LanguageChecker() - bp = BasicParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + bp = app.Decryptor.basicEncryption.basic_parent.BasicParent(lc) result = bp.decrypt("tsafkaerb hsilgne doog a ekil od yllaer i dna rehtom ym olleh rehtaf ym olleh") self.assertEqual(result['IsPlaintext?'], True) def test_basic_parent_reverse_yes_2(self): - lc = LanguageChecker() - bp = BasicParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + bp = app.Decryptor.basicEncryption.basic_parent.BasicParent(lc) result = bp.decrypt("sevom ylpmis rac eht ciffart ruoy lla gnillenut si hcihw redivorp NPV a ekilnU") self.assertEqual(result['IsPlaintext?'], True) def test_viginere_yes(self): - lc = LanguageChecker() - bp = BasicParent(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + bp = app.Decryptor.basicEncryption.basic_parent.BasicParent(lc) result = bp.decrypt("""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(result['IsPlaintext?'], True) \ No newline at end of file diff --git a/app/Tests/test_caesarcipher_basic.py b/app/Tests/test_caesarcipher_basic.py index 14fc632..6f00e7f 100644 --- a/app/Tests/test_caesarcipher_basic.py +++ b/app/Tests/test_caesarcipher_basic.py @@ -1,50 +1,58 @@ import sys -sys.path.append("..") +# sys.path.append("..") + import unittest + from app.Decryptor.basicEncryption.caesar import Caesar -from languageCheckerMod.languageChecker import LanguageChecker +import app.languageCheckerMod.LanguageChecker # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests # python3 -m unittest discover -s Tests -p test*.py # {"lc": self.lc, "IsPlaintext?": True, "Plaintext": translated, "Cipher": "Caesar"} + class TestChi(unittest.TestCase): def test_caesar_yes(self): """Checks to see if it returns True (it should)""" - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("uryyb zl sngure uryyb zl zbgure naq v ernyyl qb yvxr n tbbq ratyvfu oernxsnfg") self.assertEqual(result['IsPlaintext?'], True) + def test_caesar_no(self): """Checks to see if it returns True (it should)""" - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("o iozad iikwas") self.assertEqual(result['IsPlaintext?'], False) + def test_caesar_plaintext_yes(self): """Checks to see if it returns True (it should) Ok so this returns false becaues caesar only does up to 25, not 26 so plaintext returns false!""" - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("What about plaintext?") self.assertEqual(result['IsPlaintext?'], True) + def test_caesar_english_comparison(self): - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("Pm ol ohk hufaopun jvumpkluaphs av zhf, ol dyval pa pu jpwoly, aoha pz, if zv johunpun aol vykly vm aol slaalyz vm aol hswohila, aoha uva h dvyk jvbsk il thkl vba.") self.assertEqual(result['IsPlaintext?'], True) + def test_caesar_english_comparison_yeet(self): - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("Onrs hr mnv knbjdc enq fnnc. Sgzmj xnt zkk enq ozqshbhozshmf, zmc okdzrd bnmshmtd sn unsd enq sgd itcfdldms xnt zfqdd vhsg. Zr nsgdq trdqr gzud onhmsdc nts, sgdqd hr zcchshnmzk hmenqlzshnm sgzs NO gzr kdes nts ne sgdhq nqhfhmzk onrs sgzs sgdx gzud zccdc hm sgdhq bnlldmsr, rn okdzrd qdzc etqsgdq sn fds sgd etkk rbnod ne sgd rhstzshnm.") self.assertEqual(result['Plaintext'], "Post is now locked for good. Thank you all for participating, and please continue to vote for the judgement you agree with. As other users have pointed out, there is additional information that OP has left out of their original post that they have added in their comments, so please read further to get the full scope of the situation.".lower()) + def test_caesar_what_is_this(self): """Checks to see if it returns True (it should) Ok so this returns false becaues caesar only does up to 25, not 26 so plaintext returns false!""" - lc = LanguageChecker() - c = Caesar(lc) + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() + c = Caesar.Caesar(lc) result = c.decrypt("?") self.assertEqual(result['IsPlaintext?'], False) \ No newline at end of file diff --git a/app/Tests/test_chi_squared.py b/app/Tests/test_chi_squared.py index cf42fc0..6f67ed5 100644 --- a/app/Tests/test_chi_squared.py +++ b/app/Tests/test_chi_squared.py @@ -1,7 +1,7 @@ +import unittest import sys sys.path.append("..") -import unittest -from app.languageCheckerMod import chisquared +import app.languageCheckerMod.chisquared # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests # python3 -m unittest discover -s Tests -p test*.py @@ -9,28 +9,28 @@ from app.languageCheckerMod import chisquared class TestChi(unittest.TestCase): def test_chi_english_yes(self): """Checks to see if it returns True (it should)""" - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not """ result = self.chi.checkChi("Hello my name is Brandon and I'm a top secret message") self.assertEqual(result, True) def test_chi_english_caps(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not """ result = self.chi.checkChi("Hello My NaME IS BraNdOnnn And I LOVE You!") self.assertEqual(result, True) def tests_english_no_words(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not """ result = self.chi.checkChi("!!!!!!!!!!!!!!!!!!!") self.assertEqual(result, True) def tests_english_overflow(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not """ @@ -48,7 +48,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("cguakdbwnmfqknm ") self.assertEqual(result, False) def test_english_quckbrown(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not """ @@ -66,7 +66,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("The quick brown fox jumped over the lazy dog") self.assertEqual(result, False) def test_english_puncuation(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not Returns False because exclamation marks aren't english @@ -85,7 +85,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("!!!!!!!!!!!!!!!!!!!!!!") self.assertEqual(result, True) def test_english_one_letter(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not Returns False because exclamation marks aren't english @@ -104,7 +104,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("a") self.assertEqual(result, False) def test_english_same_letter(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not Returns False because exclamation marks aren't english @@ -123,7 +123,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz") self.assertEqual(result, False) def test_english_same_letter(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() """ Tests to see whether a sentene is classified as English or not Returns False because exclamation marks aren't english @@ -142,7 +142,7 @@ class TestChi(unittest.TestCase): result = self.chi.checkChi("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz") self.assertEqual(result, False) def test_my_chi(self): - self.chi = chisquared.chiSquared() + self.chi = app.languageCheckerMod.chisquared.chiSquared() result = self.chi.myChi(self.chi.getLetterFreq("hello this is my test"), [0.0812, 0.0271, 0.0149, 0.1202, 0.0432, 0.0203, 0.023, 0.0731, 0.0592, 0.0069, 0.001, 0.026099999999999998, 0.0398, 0.0768, 0.0695, 0.0011, 0.0182, 0.06280000000000001, 0.0602, 0.0288, 0.091, 0.0209, 0.0111, 0.021099999999999997, 0.0017000000000000001, 0.0007000000000000001]) self.assertEqual(result, 1424.8873999810571) diff --git a/app/Tests/test_integration_languagechecker.py b/app/Tests/test_integration_languagechecker.py index 9653235..17d20d1 100644 --- a/app/Tests/test_integration_languagechecker.py +++ b/app/Tests/test_integration_languagechecker.py @@ -1,24 +1,24 @@ import sys sys.path.append("..") import unittest -from languageCheckerMod.languageChecker import LanguageChecker +import app.languageCheckerMod.LanguageChecker # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests # python3 -m unittest discover -s Tests -p test*.py class TestLanguageChecker(unittest.TestCase): def test_basics(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("Hello my name is new and this is an example of some english text") self.assertEqual(result, True) def test_basics_german(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("hallo keine lieben leute nach") self.assertEqual(result, True) def test_basics_quickbrownfox(self): """ This returns true becaue by default chi squared returns true so long as it's less than 10 items it's processed """ - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") self.assertEqual(result, True) def test_basics_quickbrownfox(self): @@ -29,7 +29,7 @@ class TestLanguageChecker(unittest.TestCase): result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") self.assertEqual(result, True) def test_chi_maxima(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") @@ -46,7 +46,7 @@ class TestLanguageChecker(unittest.TestCase): result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") self.assertEqual(result, False) def test_chi_maxima_false(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") @@ -66,7 +66,7 @@ class TestLanguageChecker(unittest.TestCase): """ This returns false because s.d is not over 1 as all inputs are English """ - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("The quick brown fox jumped over the lazy dog") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") result = lc.checkLanguage("Hypertext Transfer Protocol (HTTP) parameters, including HTTP headers, allow the client and the server to pass additional information with the request or the response.") @@ -86,7 +86,7 @@ class TestLanguageChecker(unittest.TestCase): """ This returns false because s.d is not over 1 as all inputs are English """ - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("sa dew fea dxza dcsa da fsa d") result = lc.checkLanguage("df grtsf a sgrds fgserwqd") result = lc.checkLanguage("fd sa fe safsda srmad sadsa d") @@ -103,49 +103,49 @@ class TestLanguageChecker(unittest.TestCase): result = lc.checkLanguage("My friend is a really nice people who really enjoys swimming, dancing, kicking, English.") self.assertEqual(result, True) def test_integration_unusual_one(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("HELLO MY NAME IS BRANDON AND I LIKE DOLLAR") self.assertEqual(result, True) def test_integration_unusual_two(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") self.assertEqual(result, False) def test_integration_unusual_three(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("password") self.assertEqual(result, True) def test_integration_unusual_three(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("") self.assertEqual(result, False) def test_integration_unusual_four(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage(".") self.assertEqual(result, False) def test_integration_unusual_five(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("#") self.assertEqual(result, False) def test_integration_unusual_6(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("\"") self.assertEqual(result, False) def test_integration_unusual_7(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999") self.assertEqual(result, False) def test_integration_unusual_7(self): - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("") self.assertEqual(result, False) def test_integration_addition(self): """ Makes sure you can add 2 lanuggae objecs together """ - lc = LanguageChecker() + lc = app.languageCheckerMod.LanguageChecker.LanguageChecker() result = lc.checkLanguage("hello my darling") - lc2 = LanguageChecker() + lc2 = app.LanguageChecker() result = lc.checkLanguage("sad as dasr as s") temp = lc.getChiScore() diff --git a/app/Tests/test_neural_network.py b/app/Tests/test_neural_network.py index 7492251..45c38a4 100644 --- a/app/Tests/test_neural_network.py +++ b/app/Tests/test_neural_network.py @@ -1,7 +1,7 @@ import sys sys.path.append("..") import unittest -from neuralNetworkMod.nn import NeuralNetwork +import app.neuralNetworkMod.nn import numpy # python3 -m unittest Tests.testchi_squared # python -m unittest discover -s tests @@ -11,31 +11,31 @@ import numpy class TestNN(unittest.TestCase): def test_english_yes(self): """Checks to see if it returns True (it should)""" - model = NeuralNetwork() + model = app.neuralNetworkMod.nn.NeuralNetwork() result = model.predictnn("bcpvu up qvu ifs cpplt bxbz, cvu jotufbe tif qvmmfe") numpy.set_printoptions(suppress=True) result = numpy.argmax(result) self.assertEqual(result, 4) def test_sha1_yes(self): - model = NeuralNetwork() + model = app.neuralNetworkMod.nn.NeuralNetwork() result = model.predictnn("6D32263A85C7846D70439026B75758C9FC31A9B7") numpy.set_printoptions(suppress=True) result = numpy.argmax(result) self.assertEqual(result, 0) def test_md5_yes(self): - model = NeuralNetwork() + model = app.neuralNetworkMod.nn.NeuralNetwork() result = model.predictnn("5d41402abc4b2a76b9719d911017c592") numpy.set_printoptions(suppress=True) result = numpy.argmax(result) self.assertEqual(result, 1) def test_sha512_yes(self): - model = NeuralNetwork() + model = app.neuralNetworkMod.nn.NeuralNetwork() result = model.predictnn("9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043") numpy.set_printoptions(suppress=True) result = numpy.argmax(result) self.assertEqual(result, 3) def test_caesar_yes(self): - model = NeuralNetwork() + model = app.neuralNetworkMod.nn.NeuralNetwork() result = model.predictnn("bcpvu up qvu ifs cpplt bxbz, cvu jotufbe tif qvmmfe") numpy.set_printoptions(suppress=True) result = numpy.argmax(result) diff --git a/app/__main__.py b/app/__main__.py index 9b7993a..1bfc27b 100644 --- a/app/__main__.py +++ b/app/__main__.py @@ -210,7 +210,7 @@ if __name__ == "__main__": #parser.add_argument('-g','--greppable', help='Are you grepping this output?', required=False) parser.add_argument('-t','--text', help='Text to decrypt', required=False) #parser.add_argument('-s','--sicko-mode', help='If it is encrypted Ciphey WILL find it', required=False) - #parser.add_argument('-c','--cipher', help='What is the cipher used?', required=False) + parser.add_argument('-c','--cipher', help='What is the cipher used?', required=False) args = vars(parser.parse_args()) if args['cipher'] != None: diff --git a/app/languageCheckerMod/LanguageChecker.py b/app/languageCheckerMod/LanguageChecker.py index 256b873..723b1cd 100644 --- a/app/languageCheckerMod/LanguageChecker.py +++ b/app/languageCheckerMod/LanguageChecker.py @@ -46,19 +46,22 @@ In alphabetical order And you're.... Done! Make sure the name of the two match up """ from string import punctuation -#import mathsHelper -import languageCheckerMod.dictionaryChecker -import languageCheckerMod.chisquared +import app.languageCheckerMod.dictionaryChecker +import app.languageCheckerMod.chisquared +from app import languageCheckerMod + class LanguageChecker: def __init__(self): self.dictionary = languageCheckerMod.dictionaryChecker.dictionaryChecker() self.chi = languageCheckerMod.chisquared.chiSquared() + def __add__(self, otherLanguageObject): # sets the added chi squared to be of this one new = otherLanguageObject.getChiSquaredObj() + self.getChiSquaredObj() self.chi = new return self + def checkLanguage(self, text): if text == "": return False @@ -71,7 +74,9 @@ class LanguageChecker: return False else: return False + def getChiSquaredObj(self): return self.chi + def getChiScore(self): return self.chi.totalChi diff --git a/app/languageCheckerMod/chisquared.py b/app/languageCheckerMod/chisquared.py index ed73aa6..52d5376 100644 --- a/app/languageCheckerMod/chisquared.py +++ b/app/languageCheckerMod/chisquared.py @@ -10,7 +10,7 @@ Github: brandonskerritt Class calculates the Chi squared score """ -import mathsHelper +import app.mathsHelper from string import punctuation from numpy import std # I had a bug where empty string was being added to letter freq dictionary @@ -32,7 +32,7 @@ class chiSquared: self.average = 0.0 self.totalDone = 0.0 self.oldAverage = 0.0 - self.mh = mathsHelper.mathsHelper() + self.mh = app.mathsHelper.mathsHelper() self.highestLanguage = "" self.totalChi = 0.0 self.totalEqual = False diff --git a/app/languageCheckerMod/dictionaryChecker.py b/app/languageCheckerMod/dictionaryChecker.py index 9d865ad..7794817 100644 --- a/app/languageCheckerMod/dictionaryChecker.py +++ b/app/languageCheckerMod/dictionaryChecker.py @@ -1,4 +1,4 @@ -import mathsHelper +import app.mathsHelper import string class dictionaryChecker: """ @@ -12,10 +12,11 @@ class dictionaryChecker: if a string is 45% **language** words, then it's confirmed to be english """ def __init__(self): - self.mh = mathsHelper.mathsHelper() + self.mh = app.mathsHelper.mathsHelper() self.languagePercentage = 0.0 self.languageWordsCounter = 0.0 self.languageThreshold = 55 + def checkDictionary(self, text, language): """Compares a word with The dictionary is sorted and the text is sorted""" @@ -49,7 +50,7 @@ class dictionaryChecker: so we only loop once, we can do this in O(n log n) time """ counter = 0 - counterPercent = 0 + counter_percent = 0 for dictLengthCounter, word in enumerate(f): # if there is more words counted than there is text @@ -61,10 +62,10 @@ class dictionaryChecker: # counter + 1 if word in text: counter = counter + 1 - counterPercent = counterPercent + 1 + counter_percent = counter_percent + 1 self.languageWordsCounter = counter self.languagePercentage = self.mh.percentage(float(self.languageWordsCounter), float(len(text))) - return(counter) + return counter def confirmlanguage(self, text, language): self.checkDictionary(text, language) @@ -72,4 +73,3 @@ class dictionaryChecker: return True else: return False - \ No newline at end of file diff --git a/license b/license new file mode 100644 index 0000000..d9fd5e3 --- /dev/null +++ b/license @@ -0,0 +1,7 @@ +Copyright 2020 Brandon Skerritt + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1674dedc50530e7a17f73ea77207b0c0387e607a GIT binary patch literal 61807 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 E8(}G