├── LICENSE.txt ├── README.md ├── Screenshots └── 1.PNG ├── Utils ├── __pycache__ │ ├── base91.cpython-39.pyc │ ├── functions.cpython-36.pyc │ ├── functions.cpython-37.pyc │ ├── functions.cpython-39.pyc │ ├── ngram_score.cpython-36.pyc │ ├── ngram_score.cpython-37.pyc │ └── ngram_score.cpython-39.pyc ├── base91.py ├── functions.py ├── ngram_score.py ├── quadgrams.txt └── trigrams.txt ├── decoder.py └── requirements.txt /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Niraj Singh 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CTF-CryptoTool 2 | [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) 3 | [![Twitter Follow](https://img.shields.io/twitter/follow/karma9874?label=Follow&style=social)](https://twitter.com/karma9874) 4 | [![GitHub followers](https://img.shields.io/github/followers/karma9874?label=Follow&style=social)](https://github.com/karma9874) 5 | 6 | CTF-CryptoTool is a tool written in python, for breaking crypto text of CTF challenges. It tries to decode the cipher by bruteforcing it with all known cipher decoding methods easily. Also works for the cipher which does not have a key. 7 | 8 | | Known Ciphers | Known Encodings | Known Obfuscator | 9 | | ------------- |:-------------:| :-----:| 10 | | Affine Cipher | Base64 | Brainfuck | 11 | | Ceaser Cipher | Base32 | JSFuck | 12 | | Vigenere Cipher | Base85 | Ook | 13 | | Autokey Cipher | Binary | 14 | |Atbash Cipher | Octal | 15 | | Gronsfeld Cipher | Hex | 16 | | Railfence Cipher | Morse | 17 | | Keyboard Shift | Rot | 18 | | Morbit Cipher| Base58 | 19 | | Chuck Norris Unary Code | Base91 | 20 | 21 | ## Screenshots 22 | ![CTF-CryptoTool](https://github.com/karma9874/CTF-CryptoTool/blob/master/Screenshots/1.PNG) 23 | 24 | ## Installation 25 | This tool will run on python3 26 | ``` 27 | git clone https://github.com/karma9874/CTF-CryptoTool.git 28 | cd CTF-CryptoTool 29 | pip3 install -r requirements.txt 30 | ``` 31 | 32 | ## Usage 33 | ` Just throw the cipher to it ` 34 | ``` 35 | python3 decoder.py 36 | Enter the text : Feed the cipher text 37 | Enter Key : Enter key if you know any (optional) 38 | Enter flag : Enter some letters of the flag if you know (optional) 39 | Eg: While playing picoCTF you can enter the flag as picoCTF so it can match that text with the ouputs otherwise you may get much more bogus strings 40 | ``` 41 | 42 | ## Reference 43 | [python_cryptanalysis](https://github.com/jameslyons/python_cryptanalysis) -------------------------------------------------------------------------------- /Screenshots/1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Screenshots/1.PNG -------------------------------------------------------------------------------- /Utils/__pycache__/base91.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/base91.cpython-39.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/functions.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/functions.cpython-36.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/functions.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/functions.cpython-37.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/functions.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/functions.cpython-39.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/ngram_score.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/ngram_score.cpython-36.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/ngram_score.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/ngram_score.cpython-37.pyc -------------------------------------------------------------------------------- /Utils/__pycache__/ngram_score.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karma9874/CTF-CryptoTool/459b0f9f6b242cbe9f877a9339eb6ec6e9723f5b/Utils/__pycache__/ngram_score.cpython-39.pyc -------------------------------------------------------------------------------- /Utils/base91.py: -------------------------------------------------------------------------------- 1 | BASE91_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"' 2 | MASK1 = 2**13 - 1 3 | MASK2 = 2**14 - 1 4 | MASK3 = 2**8 - 1 5 | 6 | def b91encode(num): 7 | encoded = "" 8 | n = 0 9 | b = 0 10 | 11 | for digit in num.encode('latin-1'): 12 | b |= (digit << n) 13 | n += 8 14 | if n > 13: 15 | v = b & MASK1 16 | if v > 88: 17 | b >>= 13 18 | n -= 13 19 | else: 20 | v = b & MASK2 21 | b >>= 14 22 | n -= 14 23 | encoded += BASE91_ALPHA[v % 91] + BASE91_ALPHA[v // 91] 24 | if n: 25 | encoded += BASE91_ALPHA[b % 91] 26 | if n > 7 or b > 90: 27 | encoded += BASE91_ALPHA[b // 91] 28 | return encoded 29 | 30 | def b91decode(num): 31 | decoded = "" 32 | n = 0 33 | b = 0 34 | v = -1 35 | 36 | for digit in num: 37 | c = BASE91_ALPHA.index(digit) 38 | if v < 0: 39 | v = c 40 | else: 41 | v += c * 91 42 | b |= (v << n) 43 | if (v & MASK1) > 88: 44 | n += 13 45 | else: 46 | n += 14 47 | while n > 7: 48 | decoded += chr(b & MASK3) 49 | b >>= 8 50 | n -= 8 51 | v = -1 52 | if v+1: 53 | decoded += chr((b | v << n) & MASK3) 54 | return decoded 55 | 56 | def b91check(num): 57 | return set(num).issubset(set(BASE91_ALPHA)) 58 | 59 | assert b91decode(b91encode(BASE91_ALPHA)) == BASE91_ALPHA -------------------------------------------------------------------------------- /Utils/functions.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | import base64 3 | import base58 4 | from Utils.base91 import b91decode, b91check 5 | import binascii 6 | import numpy as np 7 | import re 8 | from Utils.ngram_score import ngram_score 9 | from pycipher import * 10 | from tqdm import tqdm 11 | import collections 12 | from colorama import Fore, Style,init 13 | 14 | qgram = ngram_score('Utils/quadgrams.txt') 15 | trigram = ngram_score('Utils/trigrams.txt') 16 | 17 | class nbest(object): 18 | def __init__(self,N=1000): 19 | self.store = [] 20 | self.N = N 21 | 22 | def add(self,item): 23 | self.store.append(item) 24 | self.store.sort(reverse=True) 25 | self.store = self.store[:self.N] 26 | 27 | def __getitem__(self,k): 28 | return self.store[k] 29 | 30 | def __len__(self): 31 | return len(self.store) 32 | 33 | def b64(s): 34 | try: 35 | return base64.b64decode(s).decode("utf-8") 36 | except: 37 | return 0 38 | 39 | def b32(s): 40 | try: 41 | return base64.b32decode(s).decode("utf-8") 42 | except: 43 | return 0 44 | 45 | def b58(s): 46 | try: 47 | return base58.b58decode(s).decode("utf-8") 48 | except: 49 | return 0 50 | 51 | def b85(s): 52 | try: 53 | return base64.a85decode(s).decode("utf-8") 54 | except: 55 | return 0 56 | 57 | def b91(s): 58 | try: 59 | return b91decode(s) 60 | except: 61 | return 0 62 | 63 | def hex(s): 64 | try: 65 | return binascii.unhexlify(s).decode('utf-8') 66 | except: 67 | return 0 68 | 69 | def bin(s): 70 | char="" 71 | for b in s.split(" "): 72 | try: 73 | char+= chr(int(b, 2)) 74 | except: 75 | pass 76 | return char 77 | 78 | 79 | def b85Checker(s): 80 | for i in s: 81 | if ord(i) not in range(33,117): 82 | return False 83 | return True 84 | 85 | 86 | b_32=["0","1","8","9"] 87 | MORSE_CODE_DICT = {'..-': 'U', '--..--': ', ', '....-': '4', '.....': '5', '-...': 'B', '-..-': 'X', '.-.': 'R', '--.-': 'Q', '--..': 'Z', '.--': 'W', '-..-.': '/', '..---': '2', '.-': 'A', '..': 'I', '-.-.': 'C', '..-.': 'F', '---': 'O', '-.--': 'Y', '-': 'T', '.': 'E', '.-..': 'L', '...': 'S', '-.--.-': ')', '..--..': '?', '.----': '1', '-----': '0', '-.-': 'K', '-..': 'D', '----.': '9', '-....': '6', '.---': 'J', '.--.': 'P', '.-.-.-': '.', '-.--.': '(', '--': 'M', '-.': 'N', '....': 'H', '---..': '8', '...-': 'V', '--...': '7', '--.': 'G', '...--': '3', '-....-': '-', '\n' : ' '} 88 | MORBIT = ['..', '.-', '. ', '-.', '--', '- ', ' .', ' -', ' '] 89 | lookup_table = {'A' : 'Z', 'B' : 'Y', 'C' : 'X', 'D' : 'W', 'E' : 'V','F' : 'U', 'G' : 'T', 'H' : 'S', 'I' : 'R', 'J' : 'Q', 'K' : 'P', 'L' : 'O', 'M' : 'N', 'N' : 'M', 'O' : 'L', 'P' : 'K', 'Q' : 'J', 'R' : 'I', 'S' : 'H', 'T' : 'G', 'U' : 'F', 'V' : 'E', 'W' : 'D', 'X' : 'C', 'Y' : 'B', 'Z' : 'A'} 90 | 91 | def morse(ciphertxt,flag=None): 92 | plaintxt = '' 93 | for word in ciphertxt.strip().split(" "): 94 | for c in word.strip().split(" "): 95 | if c in MORSE_CODE_DICT: 96 | plaintxt += MORSE_CODE_DICT[c] 97 | else: 98 | pass 99 | plaintxt += ' ' 100 | return plaintxt 101 | #print(Fore.GREEN+plaintxt+Fore.RESET) 102 | 103 | def unary_decode(s): 104 | b = "" 105 | decoded = "" 106 | 107 | while s: 108 | b += '0' * len(s[1]) if s[0] == "00" else '1' * len(s[1]) 109 | s = s[2:] 110 | 111 | n = int(b, 2) 112 | decoded = n.to_bytes((n.bit_length()+7)//8, byteorder="big") 113 | 114 | try: 115 | return decoded.decode() 116 | except: 117 | return 0 118 | 119 | 120 | def pretty_print(header,data): 121 | print(Fore.YELLOW+"\n"+header+" : ",Style.BRIGHT+Fore.GREEN+data+Fore.RESET) 122 | 123 | def morbit(ciphertxt,flag=None): 124 | if flag==None: 125 | flag="" 126 | scores=[] 127 | for p in permutations('123456789'): 128 | MORBIT_CODE_DICT = dict(zip(p, MORBIT)) 129 | morsetxt = "" 130 | for c in ciphertxt: 131 | if c in MORBIT_CODE_DICT: 132 | morsetxt += MORBIT_CODE_DICT[c] 133 | if flag in morse(morsetxt,flag): 134 | print(Fore.GREEN+morse(morsetxt,flag)+Fore.RESET) 135 | #scores.append((qgram.score(morse1(morsetxt,flag)),p,morse1(morsetxt,flag))) 136 | #s = sorted(scores,reverse=True) 137 | 138 | 139 | def octal(octal_str): 140 | str_converted = "" 141 | for octal_char in octal_str.strip().split(" "): 142 | try: 143 | str_converted += chr(int(octal_char, 8)) 144 | except: 145 | return 0 146 | return str_converted 147 | 148 | def atbash(message): 149 | return Atbash().decipher(message) 150 | 151 | def getIC(s): 152 | s="".join( [x.upper() for x in s.split() if x.isalpha()]) 153 | N = len(s) 154 | if N ==0: return 155 | freqs = collections.Counter(s) 156 | alphabet = map(chr, range( ord('A'), ord('Z')+1)) 157 | freqsum = 0.0 158 | for letter in alphabet: 159 | freqsum += freqs[ letter ] * ( freqs[ letter ] - 1 ) 160 | IC = freqsum / ( N*(N-1) ) 161 | return (IC,N) 162 | 163 | def keyboard_cipher(s): 164 | s=s.lower() 165 | keyboard = np.array( [ 166 | ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=' ], 167 | ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']' ], 168 | ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", '\\' ], 169 | ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '-', '='], 170 | ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=' ], 171 | ['z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '-', '='] 172 | ] 173 | ) 174 | l=[] 175 | r=[] 176 | u=[] 177 | d=[] 178 | for i in s: 179 | if i != " ": 180 | solutions = np.argwhere(keyboard == i) 181 | r.append(keyboard[solutions[0][0],solutions[0][1]+1]) 182 | l.append(keyboard[solutions[0][0],solutions[0][1]-1]) 183 | u.append(keyboard[solutions[0][0]-1,solutions[0][1]]) 184 | d.append(keyboard[solutions[0][0]+1,solutions[0][1]]) 185 | else: 186 | r.append(" ") 187 | l.append(" ") 188 | u.append(" ") 189 | d.append(" ") 190 | return l,r,u,d 191 | 192 | def rotN(s,i): 193 | abc = "abcdefghijklmnopqrstuvwxyz" 194 | return "".join([abc[(abc.find(c)+i)%26] for c in s]) 195 | 196 | def break_caesar(s): 197 | s = re.sub('[^A-Z]','',s.upper()) 198 | scores = [] 199 | for i in range(26): 200 | scores.append((qgram.score(Caesar(i).decipher(s)),i)) 201 | return max(scores) 202 | 203 | def break_affine(s): 204 | s = re.sub('[^A-Z]','',s.upper()) 205 | scores = [] 206 | for i in [1,3,5,7,9,11,15,17,19,21,23,25]: 207 | scores.extend([(qgram.score(Affine(i,j).decipher(s)),(i,j)) for j in range(0,25)]) 208 | return max(scores) 209 | 210 | def break_railfence(ctext): 211 | ctext = re.sub('[^A-Z]','',ctext.upper()) 212 | print(ctext) 213 | scores = [] 214 | for i in range(2,50): 215 | scores.append((qgram.score(Railfence(i).decipher(ctext)),i)) 216 | return max(scores) 217 | 218 | def break_3(ctext,cipher=None,Flag=None): 219 | if Flag==None: 220 | Flag="" 221 | if cipher == "b": 222 | print(Fore.YELLOW+"Breaking Beaufort Cipher"+Fore.RESET) 223 | if cipher == "a": 224 | print(Fore.YELLOW+"Breaking AutoKey Cipher"+Fore.RESET) 225 | if cipher == "v": 226 | print(Fore.YELLOW+"Breaking Vigenere Cipher"+Fore.RESET) 227 | #print("This may take a while\n") 228 | N=100 229 | ctext = re.sub(r'[^A-Z]','',ctext.upper()) 230 | for KLEN in range(3,17): 231 | rec = nbest(N) 232 | for i in permutations('ABCDEFGHIJKLMNOPQRSTUVWXYZ',3): 233 | key = ''.join(i) + 'A'*(KLEN-len(i)) 234 | if cipher=='b': 235 | pt = Beaufort(key).decipher(ctext) 236 | elif cipher=='a': 237 | pt = Autokey(key).decipher(ctext) 238 | elif cipher=='v': 239 | pt = Vigenere(key).decipher(ctext) 240 | score = 0 241 | for j in range(0,len(ctext),KLEN): 242 | score += trigram.score(pt[j:j+3]) 243 | rec.add((score,''.join(i),pt[:30])) 244 | next_rec = nbest(N) 245 | for i in range(0,KLEN-3): 246 | for k in range(N): 247 | for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': 248 | key = rec[k][1] + c 249 | fullkey = key + 'A'*(KLEN-len(key)) 250 | if cipher=='b': 251 | pt = Beaufort(fullkey).decipher(ctext) 252 | elif cipher=='a': 253 | pt = Autokey(fullkey).decipher(ctext) 254 | elif cipher=='v': 255 | pt = Vigenere(fullkey).decipher(ctext) 256 | score = 0 257 | for j in range(0,len(ctext),KLEN): 258 | score += qgram.score(pt[j:j+len(key)]) 259 | next_rec.add((score,key,pt[:30])) 260 | rec = next_rec 261 | next_rec = nbest(N) 262 | bestkey = rec[0][1] 263 | if cipher=='b': 264 | pt = Beaufort(bestkey).decipher(ctext) 265 | elif cipher=='a': 266 | pt = Autokey(bestkey).decipher(ctext) 267 | elif cipher=='v': 268 | pt = Vigenere(bestkey).decipher(ctext) 269 | bestscore = qgram.score(pt) 270 | for i in range(N): 271 | if cipher=='b': 272 | pt = Beaufort(rec[i][1]).decipher(ctext) 273 | elif cipher=='a': 274 | pt = Autokey(rec[i][1]).decipher(ctext) 275 | elif cipher=='v': 276 | pt = Vigenere(rec[i][1]).decipher(ctext) 277 | score = qgram.score(pt) 278 | if score > bestscore: 279 | bestkey = rec[i][1] 280 | bestscore = score 281 | if cipher=='b': 282 | if Flag in Beaufort(bestkey).decipher(ctext): 283 | print("Decoded String",Fore.GREEN+Beaufort(bestkey).decipher(ctext)+Fore.RESET,'Key: '+Fore.BLUE+bestkey+Fore.RESET) 284 | elif cipher=='a': 285 | if Flag in Autokey(bestkey).decipher(ctext): 286 | print("Decoded String",Fore.GREEN+Autokey(bestkey).decipher(ctext)+Fore.RESET,'Key: '+Fore.BLUE+bestkey+Fore.RESET) 287 | elif cipher=='v': 288 | if Flag in Vigenere(bestkey).decipher(ctext): 289 | print("Decoded String",Fore.GREEN+Vigenere(bestkey).decipher(ctext)+Fore.RESET,'Key: '+Fore.BLUE+bestkey+Fore.RESET) 290 | 291 | def break_gronsfeld(ctext,Flag=None): 292 | if Flag == None: 293 | Flag="" 294 | print(Fore.YELLOW+"Breaking Gronsfeld Cipher"+Fore.RESET) 295 | #print("This may take a while\n") 296 | ctext = re.sub(r'[^A-Z]','',ctext.upper()) 297 | N=100 298 | for KLEN in range(3,17): 299 | rec = nbest(N) 300 | for i in permutations('0123456789',3): 301 | key = ''.join(i) + '0'*(KLEN-len(i)) 302 | key = [int(i) for i in list(key)] 303 | pt = Gronsfeld(list(key)).decipher(ctext) 304 | score = 0 305 | for j in range(0,len(ctext),KLEN): 306 | score += trigram.score(pt[j:j+3]) 307 | rec.add((score,''.join(i),pt[:30])) 308 | 309 | next_rec = nbest(N) 310 | for i in range(0,KLEN-3): 311 | for k in range(N): 312 | for c in '0123456789': 313 | key = rec[k][1] + c 314 | fullkey = key + '0'*(KLEN-len(key)) 315 | fullkey = [int(i) for i in list(fullkey)] 316 | pt = Gronsfeld(list(fullkey)).decipher(ctext) 317 | score = 0 318 | for j in range(0,len(ctext),KLEN): 319 | score += qgram.score(pt[j:j+len(key)]) 320 | next_rec.add((score,key,pt[:30])) 321 | rec = next_rec 322 | next_rec = nbest(N) 323 | bestkey = rec[0][1] 324 | bestkey = [int(i) for i in list(bestkey)] 325 | pt = Gronsfeld(list(bestkey)).decipher(ctext) 326 | bestscore = qgram.score(pt) 327 | for i in range(N): 328 | scam = list(rec[i][1]) 329 | scam = [int(i) for i in scam] 330 | pt = Gronsfeld(scam).decipher(ctext) 331 | score = qgram.score(pt) 332 | if score > bestscore: 333 | bestkey = scam 334 | bestscore = score 335 | if Flag in Gronsfeld(bestkey).decipher(ctext): 336 | print("Decoded String",Fore.GREEN+Gronsfeld(bestkey).decipher(ctext)+Fore.RESET,'Key: ['+Fore.BLUE+''.join(str(x) for x in bestkey)+Fore.RESET+']') 337 | -------------------------------------------------------------------------------- /Utils/ngram_score.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Allows scoring of text using n-gram probabilities 3 | 17/07/12 4 | ''' 5 | from math import log10 6 | 7 | class ngram_score(object): 8 | def __init__(self,ngramfile,sep=' '): 9 | ''' load a file containing ngrams and counts, calculate log probabilities ''' 10 | self.ngrams = {} 11 | for line in open(ngramfile): 12 | key,count = line.split(sep) 13 | self.ngrams[key] = int(count) 14 | self.L = len(key) 15 | self.N = sum(self.ngrams.values()) 16 | #calculate log probabilities 17 | for key in self.ngrams.keys(): 18 | self.ngrams[key] = log10(float(self.ngrams[key])/self.N) 19 | self.floor = log10(0.01/self.N) 20 | 21 | def score(self,text): 22 | ''' compute the score of text ''' 23 | score = 0 24 | ngrams = self.ngrams.__getitem__ 25 | for i in range(len(text)-self.L+1): 26 | if text[i:i+self.L] in self.ngrams: score += ngrams(text[i:i+self.L]) 27 | else: score += self.floor 28 | return score 29 | -------------------------------------------------------------------------------- /decoder.py: -------------------------------------------------------------------------------- 1 | import re 2 | from Utils.functions import * 3 | from pycipher import * 4 | from colorama import Fore, Style,init 5 | 6 | 7 | banner=""" 8 | _____ ___________ _____ _ _____ _ 9 | / __ \_ _| ___| / __ \ | | |_ _| | | 10 | | / \/ | | | |_ ______| / \/_ __ _ _ _ __ | |_ ___ | | ___ ___ | | 11 | | | | | | _|______| | | '__| | | | '_ \| __/ _ \| |/ _ \ / _ \| | 12 | | \__/\ | | | | | \__/\ | | |_| | |_) | || (_) | | (_) | (_) | | 13 | \____/ \_/ \_| \____/_| \__, | .__/ \__\___/\_/\___/ \___/|_| 14 | __/ | | 15 | |___/|_| 16 | """ 17 | 18 | print(Style.BRIGHT+Fore.GREEN+banner+Fore.RESET) 19 | 20 | string = input("Enter the text : ") 21 | key = input("Enter Key (if none press enter): ") 22 | flag = input("Enter flag (if none press enter): ") 23 | 24 | if flag==None: 25 | flag="" 26 | 27 | ic=getIC(string) 28 | print('ic',ic) 29 | result="" 30 | 31 | if not key: 32 | if set(string).issubset({'0', '1',' '}): 33 | res=bin(string) 34 | if res: 35 | pretty_print("Possible Binary",res) 36 | #print(Fore.YELLOW+"\nPossible Binary : ",Style.BRIGHT+Fore.GREEN+bin(string)+Fore.RESET) 37 | 38 | if len(string)%8==0 or string[-1]=="=" and any(x not in string for x in b_32): 39 | res=b32(string) 40 | if res: 41 | pretty_print("Possible Base32",res) 42 | #print(Fore.YELLOW+"\nPossible Base32 : ",Fore.GREEN+b32(string)+Fore.RESET) 43 | 44 | if len(string)%4==0 or string[-1]== '=' and len(set(string))<=65: 45 | res = b64(string) 46 | if res: 47 | pretty_print("Possible Base64",res) 48 | 49 | if ('I' not in string) and ('O' not in string) and ('l' not in string) and (len(set(string)) < 58) and ('0' not in string): 50 | res = b58(string) 51 | if res: 52 | pretty_print("Possible Base58", res) 53 | 54 | if set(string).issubset({'-', '.','/'," "}): 55 | res = morse(string,flag) 56 | pretty_print("Possible Morse",res) 57 | 58 | if re.search(r'[0-9a-fA-F]+',string): 59 | res = hex(string) 60 | if res: 61 | pretty_print("Possible Hex",res) 62 | 63 | if b85Checker(string): 64 | res = b85(string) 65 | if res: 66 | pretty_print("Possible Base85",res) 67 | 68 | if b91check(string): 69 | res = b91(string) 70 | if res: 71 | pretty_print("Possible Base91",res) 72 | 73 | s = string.split(' ') 74 | try: 75 | if s[0] == s[4]: 76 | if s[0] == s[4]: 77 | res = unary_decode(s) 78 | if res: 79 | pretty_print("Possible Chuck Norris Unary Code",res) 80 | except IndexError: 81 | # Handle the situation where s does not have 5 elements 82 | print("Error: The list 's' does not have enough elements... Skipping mighty chuck norris") 83 | 84 | 85 | if re.search(r'^[1-9]+$',string): 86 | print(Fore.YELLOW+"\nPossible Morbit ") 87 | morbit(string,flag) 88 | 89 | if re.search(r"^[0-7\s]+$",string): 90 | res = octal(string) 91 | if res: 92 | pretty_print("Possible Octal",res) 93 | 94 | if set(string).issubset({">","<","+","-",".","[","]"," "}): 95 | pretty_print("Possible brainfuck","https://www.dcode.fr/brainfuck-language") 96 | 97 | if set(string).issubset({"Ook.","Ook?","Ook!"}): 98 | pretty_print("Possible ook","https://www.dcode.fr/ook-language") 99 | 100 | 101 | if set(string).issubset({"(","!","[","]","+",")"}): 102 | pretty_print("Possible Jsfuck","https://enkhee-osiris.github.io/Decoder-JSFuck/") 103 | 104 | 105 | if ic != None and ic[0] > 0.02: 106 | print(Fore.YELLOW+"\nPossible Keyboard Shift Cipher"+Fore.RESET) 107 | # a,b,c,d = keyboard_cipher(string) 108 | # print("Right Shift :",Fore.GREEN+''.join(a)+Fore.RESET) 109 | # print("Left Shift :",Fore.GREEN+''.join(b)+Fore.RESET) 110 | # print("Up Shift :",Fore.GREEN+''.join(c)+Fore.RESET) 111 | # print("Down Shift :",Fore.GREEN+''.join(d)+Fore.RESET) 112 | max_key = break_caesar(string) 113 | if flag.lower() in Caesar(max_key[1]).decipher(string).lower(): 114 | print(Fore.YELLOW+"\nPossible Caesar Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Caesar(max_key[1]).decipher(string)+Fore.RESET,"Key:",Fore.BLUE+str(max_key[1])) 115 | if flag.lower() in atbash(string).lower(): 116 | print(Fore.YELLOW+"\nPossible Atbash Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,atbash(string)) 117 | print(Fore.YELLOW+"\nPossible Vigenere Cipher") 118 | break_3(string,"v",flag) 119 | print(Fore.YELLOW+"\nPossible Beaufort Cipher") 120 | break_3(string,"b",flag) 121 | print(Fore.YELLOW+"\nPossible Gronsfeld Cipher") 122 | break_gronsfeld(string,flag) 123 | max_key = break_caesar(string) 124 | max_key = break_affine(string) 125 | if flag.lower() in Affine(max_key[1][0],max_key[1][1]).decipher(string).lower(): 126 | print(Fore.YELLOW+"\nPossible Affine Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Affine(max_key[1][0],max_key[1][1]).decipher(string)+Fore.RESET,"Key:",Fore.BLUE+str(max_key)) 127 | print(Fore.YELLOW+"\nPossible ROT Cipher\nBreaking ROT") 128 | for i in range(2,30): 129 | if flag.lower() in rotN(string,i).lower(): 130 | print(Fore.YELLOW+"Decoded String:",Fore.GREEN+rotN(string,i)+Fore.RESET,Fore.BLUE+"Rot"+str(i)) 131 | max_key = break_railfence(string) 132 | if flag.lower() in Railfence(max_key[1]).decipher(string).lower(): 133 | print(Fore.YELLOW+"\nPossible Railfence Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Railfence(max_key[1]).decipher(string)+Fore.RESET,"Key:",Fore.BLUE+str(max_key[1])) 134 | print(Fore.YELLOW+"\nPossible Autokey Cipher") 135 | break_3(string,"a",flag) 136 | print(Fore.YELLOW+"\nPossible Substitution Cipher","use quipquip") 137 | else: 138 | string=string.lower().replace(" ","") 139 | print(string) 140 | if len(key)==1 and key.isdigit(): 141 | print(Fore.YELLOW+"\nPossible Caesar Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Caesar(key).decipher(string)) 142 | print(Fore.YELLOW+"\nPossible Railfence Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Railfence(key).decipher(string)) 143 | if key.isalpha(): 144 | print(Fore.YELLOW+"\nPossible Vigenere Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Vigenere(key).decipher(string)) 145 | print(Fore.YELLOW+"\nPossible Beaufort Cipher"+Fore.RESET,"Decoded String:"+Fore.GREEN,Beaufort(key).decipher(string)) 146 | if all(isinstance(item, int) for item in key): 147 | print(Fore.YELLOW+"\nPossible Gronsfeld Cipher"+Fore.RESET,"Decoded String:",Gronsfeld(list(key)).decipher(string)) 148 | if " " in key: 149 | key_set - key.split(" ") 150 | print(Fore.YELLOW+"\nPossible Affine Cipher"+Fore.RESET,"Decoded String:",Affine(key_set[0],key_set[1]).decipher(string)) 151 | print(Fore.YELLOW+"\nPossible Autokey Cipher"+Fore.RESET,"Decoded String:",Autokey(key).decipher(string)) 152 | if len(key)==26: 153 | print(Fore.YELLOW+"\nPossible Substitution Cipher"+Fore.RESET,"Decoded String:",SimpleSubstitution(key).decipher(string)) 154 | if len(key)==25: 155 | print(Fore.YELLOW+"\nPossible playfair Cipher"+Fore.RESET,"Decoded String:",Playfair(key).decipher(string)) 156 | 157 | #print("\nPossible Polybius Cipher","Decoded String:",Polybius(key).decipher(string)) 158 | 159 | 160 | 161 | #nGmni Tskcxipo esdskkxgmejvc 162 | 163 | # if ic[0] < 0.055 and ic[0] >= 0.035 : 164 | # max_key = break_caesar(string) 165 | # if flag in Caesar(max_key[1]).decipher(string): 166 | # print("Possible Caesar Cipher","Decoded String:",Caesar(max_key[1]).decipher(string),"Key:",max_key[1]) 167 | # # else: 168 | # # if mode: 169 | # # print("Possible Caesar Cipher","Decoded String:",Caesar(max_key[1]).decipher(string),"Key:",max_key[1]) 170 | # print("Possible Vigenere Cipher") 171 | # break_3(string,"v",flag) 172 | # print("Possible Beaufort Cipher") 173 | # break_3(string,"b",flag) 174 | # print("Possible Gronsfeld Cipher") 175 | # break_gronsfeld(string,flag) 176 | # elif ic[0]>=0.06: 177 | # max_key = break_caesar(string) 178 | # if flag in Caesar(max_key[1]).decipher(string): 179 | # print("Possible Caesar Cipher","Decoded String:",Caesar(max_key[1]).decipher(string),"Key:",max_key[1]) 180 | # max_key = break_affine(string) 181 | # if flag in Affine(max_key[1][0],max_key[1][1]).decipher(string): 182 | # print("Possible Affine Cipher","Decoded String:",Affine(max_key[1][0],max_key[1][1]).decipher(string),"Key:",max_key) 183 | # print("Possible ROT Cipher\nBreaking ROT") 184 | # for i in range(2,30): 185 | # if flag in rotN(string,i): 186 | # print("Decoded String:",rotN(string,i),"Rot"+str(i)) 187 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pycipher 3 | colorama 4 | base58 5 | --------------------------------------------------------------------------------