예제 #1
0
	def test_decrypt(self):
		cipher = Transposition()
		open_text = normalize_text("Python is a general-purpose, interpreted high-level programming language")
		key = "password"
		cipher_text = cipher.encrypt(open_text, key)
		decrypted_text = cipher.decrypt(cipher_text, key)
		expected = open_text + "xx"
		self.assertEqual(decrypted_text, expected)
예제 #2
0
class LongWordAttack(object):
    """Cryptanalysis method for transposition cipher"""
    def __init__(self):
        super(LongWordAttack, self).__init__()
        self.max_keylen = 15
        self.transposition = Transposition()

    def crack(self, cipher_text, langstats):
        key_text_pair = lambda key: (
            key, self.transposition.decrypt(cipher_text, key))
        key_text = (key_text_pair(key)
                    for key in self._get_possible_keys(cipher_text, langstats))
        return langstats.most_meaningful(key_text)

    def _get_possible_keys(self, cipher_text, langstats):
        reshuffle_text = self.transposition._partition_text_decrypt
        for keylen in self._key_lengths(cipher_text):
            all_words = langstats.get_words(keylen)
            for cipher_word in reshuffle_text(cipher_text,
                                              len(cipher_text) / keylen):
                cipher_counter = Counter(cipher_word)
                for real_word in all_words:
                    if Counter(real_word) == cipher_counter:
                        for key in self._get_valid_keys(
                                cipher_word, real_word):
                            yield key

    def _get_valid_keys(self, cipher_word, real_word):
        for perm in self._get_perms(cipher_word, 0, [],
                                    self.get_positions(real_word)):
            yield "".join(chr(x + ord('a')) for x in perm)

    def _get_perms(self, word, currPos, visited, positions):
        if currPos == len(word):
            yield visited
        else:
            c = word[currPos]
            for free in positions[c] - set(visited):
                for vis in self._get_perms(word, currPos + 1, visited + [free],
                                           positions):
                    yield vis

    def get_positions(self, word):
        pos = {}
        for i, char in enumerate(word):
            if char in pos:
                pos[char].add(i)
            else:
                pos[char] = {i}
        return pos

    def _key_lengths(self, cipher_text):
        ltext = len(cipher_text)
        return (i for i in range(2, self.max_keylen + 1) if ltext % i == 0)
예제 #3
0
class LongWordAttack(object):
	"""Cryptanalysis method for transposition cipher"""
	def __init__(self):
		super(LongWordAttack, self).__init__()
		self.max_keylen = 15
		self.transposition = Transposition()

	def crack(self, cipher_text, langstats):
		key_text_pair = lambda key: (key, self.transposition.decrypt(cipher_text, key))
		key_text = (key_text_pair(key) for key in self._get_possible_keys(cipher_text, langstats))
		return langstats.most_meaningful(key_text)

	def _get_possible_keys(self, cipher_text, langstats):
		reshuffle_text = self.transposition._partition_text_decrypt
		for keylen in self._key_lengths(cipher_text):
			all_words = langstats.get_words(keylen)
			for cipher_word in reshuffle_text(cipher_text, len(cipher_text) / keylen):
				cipher_counter = Counter(cipher_word)
				for real_word in all_words:
					if Counter(real_word) == cipher_counter:
						for key in self._get_valid_keys(cipher_word, real_word):
							yield key

	def _get_valid_keys(self, cipher_word, real_word):
		for perm in self._get_perms(cipher_word, 0, [], self.get_positions(real_word)):
			yield "".join(chr(x + ord('a')) for x in perm)

	def _get_perms(self, word, currPos, visited, positions):
		if currPos == len(word):
			yield visited
		else:
			c = word[currPos]
			for free in positions[c] - set(visited):
				for vis in self._get_perms(word, currPos + 1, visited + [free], positions):
					yield vis

	def get_positions(self, word):
		pos = {}
		for i, char in enumerate(word):
			if char in pos:
				pos[char].add(i)
			else:
				pos[char] = {i}
		return pos

	def _key_lengths(self, cipher_text):
		ltext = len(cipher_text)
		return (i for i in range(2, self.max_keylen + 1) if ltext % i == 0)