def _crackRepeatingXOR(byteObject, frequentLetters, keySizeRange, blockNumber): if not isBytes(byteObject): raise ValueError("Input must be a bytes object") keySizes = getLikelyKeySizes(byteObject, keySizeRange, blockNumber, howMany=3) bestGuess = Candidate(0, b'', b'', b'') for keySize in keySizes: blocks = divideIntoBlocks(byteObject, keySize) possibleKey = bytearray() for block in blocks: candidate = _crackSingleXOR(block, frequentLetters) # This key length can never be the correct key length if candidate.key == b'': break possibleKey.append(candidate.key[0]) if len(possibleKey) != keySize: continue possibleKey = bytes(possibleKey) secret = fixedXOR(byteObject, repeatPerCharacter(possibleKey, len(byteObject))) score = calculateScore(secret, frequentLetters) if score > bestGuess.score and encodedByUTF8(secret): bestGuess = Candidate(score, possibleKey, byteObject, secret) return bestGuess
def _crackSingleXOR(byteObject, frequentLetters): if not isBytes(byteObject): raise ValueError("Input must be a bytes object") bestCandidate = Candidate(0, b'', b'', b'') # We skip 0, since XORing against a bunch of 0s isn't going to do anything byteLength = len(byteObject) for i in range(1, 256): possibleKey = repeatPerCharacter(bytes([i]), byteLength) secret = fixedXOR(byteObject, possibleKey) score = calculateScore(secret, frequentLetters) if score > bestCandidate.score and encodedByUTF8(secret): bestCandidate = Candidate(score, possibleKey, byteObject, secret) return bestCandidate
def crackXOR(byteObject, scoreFile, EType): if not isBytes(byteObject): byteObject = hex2bytes(byteObject) if isHex( byteObject) else byteObject.encode() frequentLetters = { key.encode(): value for key, value in readJSON(scoreFile).items() } if EType == XORType.SINGLE: return _crackSingleXOR(byteObject, frequentLetters) elif EType == XORType.REPEATING: return _crackRepeatingXOR(byteObject, frequentLetters, keySizeRange=(2, 40), blockNumber=4) else: raise NotImplementedError
def test_3_check_bytes_with_invalid_bytes(self): b = 'deadbeef' assert not isBytes(bytes)
def test_2_check_bytes_with_valid_bytes(self): b = bytes.fromhex('deadbeef') assert isBytes(b)