def attemptCrack(self, ctext: str) -> List[CrackResult]: logger.debug(f"Trying ASCII shift cipher on {ctext}") logger.trace("Beginning cipheycore simple analysis") # Hand it off to the core analysis = self.cache.get_or_update( ctext, "cipheycore::simple_analysis", lambda: cipheycore.analyse_string(ctext), ) logger.trace("Beginning cipheycore::caesar") possible_keys = cipheycore.caesar_crack(analysis, self.expected, self.group, self.p_value) n_candidates = len(possible_keys) logger.debug(f"ASCII shift returned {n_candidates} candidates") if n_candidates == 0: logger.trace("Filtering for better results") analysis = cipheycore.analyse_string(ctext, self.group) possible_keys = cipheycore.caesar_crack(analysis, self.expected, self.group, self.p_value) candidates = [] for candidate in possible_keys: logger.trace( f"Candidate {candidate.key} has prob {candidate.p_value}") translated = cipheycore.caesar_decrypt(ctext, candidate.key, self.group) candidates.append( CrackResult(value=translated, key_info=candidate.key)) return candidates
def attemptCrack(self, ctext: str) -> List[CrackResult]: logging.info("Trying vigenere cipher") # Convert it to lower case if self.lower: message = ctext.lower() else: message = ctext # Analysis must be done here, where we know the case for the cache if self.keysize is not None: return self.crackOne( message, self.cache.get_or_update( ctext, f"vigenere::{self.keysize}", lambda: cipheycore.analyse_string( message, self.keysize, self.group ), ), ctext, ) arrs = [] likely_lens = self.cache.get_or_update( ctext, "vigenere::likely_lens", lambda: cipheycore.vigenere_likely_key_lens( message, self.expected, self.group ), ) possible_lens = [i for i in likely_lens] possible_lens.sort(key=lambda i: i.p_value) logging.debug(f"Got possible lengths {[i.len for i in likely_lens]}") # TODO: work out length for i in possible_lens: arrs.extend( self.crackOne( message, self.cache.get_or_update( ctext, f"vigenere::{i.len}", lambda: cipheycore.analyse_string(message, i.len, self.group), ), ctext, ) ) logging.info(f"Vigenere returned {len(arrs)} candidates") return arrs
def checkChi(self, text): if text is None: return False if type(text) is bytes: try: text = text.decode() except: return None """Checks to see if the Chi score is good if it is, it returns True Call this when you want to determine whether something is likely to be Chi or not Arguments: * text - the text you want to run a Chi Squared score on Outputs: * True - if it has a significantly lower chi squared score * False - if it doesn't have a significantly lower chi squared score """ # runs after every chi squared to see if it's 1 significantly lower than averae # the or statement is bc if the program has just started I don't want it to ignore the # ones at the start analysis = cipheycore.analyse_string(text) chisq = cipheycore.chisq_test(analysis, self.language) logger.debug(f"Chi-squared p-value is {chisq}") return chisq > self.chiSquaredSignificanceThreshold
def plaintext_probability(self, translated: str) -> float: """ Analyses the translated text and applies the chi squared test to see if it is a probable plaintext candidate Returns the probability of the chi-squared test. """ analysis = cipheycore.analyse_string(translated) return cipheycore.chisq_test(analysis, self.expected)
def cached_freq_analysis(ctext, config): base = config.objs.setdefault("cached_freq_analysis", ctext) res = base.get("cached_freq_analysis") if res is not None: return res base["cached_freq_analysis"] = cipheycore.analyse_string(ctext)
def attemptCrack(self, ctext: str) -> List[CrackResult]: logger.debug("Trying caesar cipher") # Convert it to lower case # # TODO: handle different alphabets if self.lower: message = ctext.lower() else: message = ctext logger.trace("Beginning cipheycore simple analysis") # Hand it off to the core analysis = self.cache.get_or_update( ctext, "cipheycore::simple_analysis", lambda: cipheycore.analyse_string(message), ) logger.trace("Beginning cipheycore::caesar") possible_keys = cipheycore.caesar_crack(analysis, self.expected, self.group, True, self.p_value) n_candidates = len(possible_keys) logger.debug(f"Caesar returned {n_candidates} candidates") candidates = [] for candidate in possible_keys: translated = cipheycore.caesar_decrypt(message, candidate.key, self.group) candidates.append( CrackResult(value=translated, key_info=candidate.key)) return candidates
def getInfo(self, ctext: str) -> CrackInfo: if self.keysize is not None: analysis = self.cache.get_or_update( ctext, f"vigenere::{self.keysize}", lambda: cipheycore.analyse_string( ctext.lower(), self.keysize, self.group ), ) val = cipheycore.vigenere_detect(analysis, self.expected) logging.info(f"Vigenere has likelihood {val}") return CrackInfo( success_likelihood=val, # TODO: actually calculate runtimes success_runtime=1e-3, failure_runtime=1e-2, ) likely_lens = self.cache.get_or_update( ctext, "vigenere::likely_lens", lambda: cipheycore.vigenere_likely_key_lens( ctext.lower(), self.expected, self.group, self.detect_p_value ), ) # Filter out the lens that make no sense likely_lens = [i for i in likely_lens if i.len <= self.max_key_length] for keysize in likely_lens: # Store the analysis analysis = self.cache.get_or_update( ctext, f"vigenere::{keysize.len}", lambda: keysize.tab ) if len(likely_lens) == 0: return CrackInfo( success_likelihood=0, # TODO: actually calculate runtimes success_runtime=2e-3, failure_runtime=2e-2, ) logging.info( f"Vigenere has likelihood {likely_lens[0].p_value} with lens {[i.len for i in likely_lens]}" ) return CrackInfo( success_likelihood=likely_lens[0].p_value, # TODO: actually calculate runtimes success_runtime=2e-4, failure_runtime=2e-4, )
def getInfo(self, ctext: str) -> CrackInfo: analysis = self.cache.get_or_update( ctext, "cipheycore::simple_analysis", lambda: cipheycore.analyse_string(ctext), ) return CrackInfo( success_likelihood=cipheycore.caesar_detect(analysis, self.expected), # TODO: actually calculate runtimes success_runtime=1e-5, failure_runtime=1e-5, )
def attemptCrack(self, ctext: str) -> List[CrackResult]: logger.debug("Trying vigenere cipher") # Convert it to lower case if self.lower: message = ctext.lower() else: message = ctext # Analysis must be done here, where we know the case for the cache if self.keysize is not None: return self.crackOne( message, self.cache.get_or_update( ctext, f"vigenere::{self.keysize}", lambda: cipheycore.analyse_string(ctext, self.keysize, self.group), ), ) else: arrs = [] possible_len = self.kasiskiExamination(message) possible_len.sort() logger.trace(f"Got possible lengths {possible_len}") # TODO: work out length for i in possible_len: arrs.extend( self.crackOne( message, self.cache.get_or_update( ctext, f"vigenere::{i}", lambda: cipheycore.analyse_string(ctext, i, self.group), ), ) ) logger.debug(f"Vigenere returned {len(arrs)} candidates") return arrs
def getInfo(self, ctext: str) -> CrackInfo: if self.keysize is not None: analysis = self.cache.get_or_update( ctext, f"vigenere::{self.keysize}", lambda: cipheycore.analyse_string(ctext, self.keysize, self. group), ) return CrackInfo( success_likelihood=cipheycore.vigenere_detect( analysis, self.expected), # TODO: actually calculate runtimes success_runtime=1e-4, failure_runtime=1e-4, ) likely_lens = self.cache.get_or_update( ctext, f"vigenere::likely_lens", lambda: cipheycore.vigenere_likely_key_lens( ctext, self.expected, self.group, self.p_value), ) for keysize in likely_lens: # Store the analysis analysis = self.cache.get_or_update(ctext, f"vigenere::{keysize.len}", lambda: keysize.tab) if len(likely_lens) == 0: return CrackInfo( success_likelihood=0, # TODO: actually calculate runtimes success_runtime=2e-4, failure_runtime=2e-4, ) return CrackInfo( success_likelihood=0 * likely_lens[0].p_value, # TODO: actually calculate runtimes success_runtime=2e-4, failure_runtime=2e-4, )
def getInfo(self, ctext: T) -> CrackInfo: if self.keysize is not None: analysis = self.cache.get_or_update( ctext, f"vigenere::{self.keysize}", lambda: cipheycore.analyse_string(ctext, self.keysize, self.group), ) return CrackInfo( success_likelihood=cipheycore.vigenere_detect(analysis, self.expected), # TODO: actually calculate runtimes success_runtime=1e-4, failure_runtime=1e-4, ) else: return CrackInfo( success_likelihood=0.5, # TODO: actually work this out # TODO: actually calculate runtimes success_runtime=1e-4, failure_runtime=1e-4, )
def decrypt(self, message): logger.debug("Trying caesar Cipher") # Convert it to lower case # # TODO: handle different alphabets message = message.lower() # Hand it off to the core group = cipheydists.get_charset("english")["lcase"] expected = cipheydists.get_dist("lcase") analysis = cipheycore.analyse_string(message) possible_keys = cipheycore.caesar_crack(analysis, expected, group) n_candidates = len(possible_keys) logger.debug(f"Caesar cipher core heuristic returned {n_candidates} candidates") for candidate in possible_keys: translated = cipheycore.caesar_decrypt(message, candidate.key, group) result = self.lc.checkLanguage(translated) if result: logger.debug(f"Caesar cipher returns true {result}") return { "lc": self.lc, "IsPlaintext?": True, "Plaintext": translated, "Cipher": "Caesar", "Extra Information": f"The rotation used is {candidate.key}", } # if none of them match English, return false! logger.debug(f"Caesar cipher returns false") return { "lc": self.lc, "IsPlaintext?": False, "Plaintext": None, "Cipher": "Caesar", "Extra Information": None, }
def getInfo(self, ctext: bytes) -> CrackInfo: if self.keysize is not None: analysis = self.cache.get_or_update( ctext, f"xorcrypt::{self.keysize}", lambda: cipheycore.analyse_string(ctext, self.keysize, self. group), ) return CrackInfo( success_likelihood=cipheycore.xorcrypt_detect( analysis, self.expected), # TODO: actually calculate runtimes success_runtime=1e-4, failure_runtime=1e-4, ) keysize = self.cache.get_or_update( ctext, f"xorcrypt::likely_lens", lambda: cipheycore.xorcrypt_guess_len(ctext), ) if keysize == 1: return CrackInfo( success_likelihood=0, # TODO: actually calculate runtimes success_runtime=2e-3, failure_runtime=2e-2, ) return CrackInfo( success_likelihood=0.9, # Dunno, but it's quite likely # TODO: actually calculate runtimes success_runtime=2e-3, failure_runtime=2e-2, )
import json import sys import cipheycore data = sys.stdin.read() analysis = cipheycore.analyse_string(data) print(json.dumps({i: j / len(data) for i, j in analysis.freqs.items()}))