2015-10-25 5 views
0

Я пытался реализовать однобайтовое дешифрование XOR в python. Когда я запускаю это в python2.7 я получаю желаемое значение
(88, "Cooking MC's like a pound of bacon")
Но при запуске в python3.2 я получить
(0, b'\x1b77316?x\x15\x1b\x7f+x413=x9x(7-6<x7>x:9;76')Различные выходы для разных питонов Интерпретаторы

Вот мой код.

''' 
Created on Oct 24, 2015 

Matasano Crypto Challenge 3 
''' 

import binascii 
from Crypto.Util.strxor import strxor_c 
from collections import Counter 
import math 

FREQUENCY_TABLE = { 
    b'a': 0.08167, 
    b'b': 0.01492, 
    b'c': 0.02782, 
    b'd': 0.04253, 
    b'e': 0.1270, 
    b'f': 0.02228, 
    b'g': 0.02015, 
    b'h': 0.06094, 
    b'i': 0.06966, 
    b'j': 0.00153, 
    b'k': 0.00772, 
    b'l': 0.04025, 
    b'm': 0.02406, 
    b'n': 0.06749, 
    b'o': 0.07507, 
    b'p': 0.01929, 
    b'q': 0.00095, 
    b'r': 0.05987, 
    b's': 0.06327, 
    b't': 0.09056, 
    b'u': 0.02758, 
    b'v': 0.00978, 
    b'w': 0.02360, 
    b'x': 0.00150, 
    b'y': 0.01974, 
    b'z': 0.00074, 
} 

def englishness(a): 
    c = Counter(a.lower()) 
    total_characters = len(a) 
    coefficient = sum(math.sqrt(FREQUENCY_TABLE.get(char, 0) * y/total_characters) for char,y in c.items()) 
    print (coefficient) 
    return coefficient 

def answer(s): 
    print (s) 
    def compfunc(items): 
     return englishness(items[1]) 
    return max([(i, strxor_c(s,i)) for i in range(0,256)], key = compfunc) 

if __name__ == '__main__': 
    encodedS = b'1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736' 
    S = binascii.unhexlify(encodedS) 
    print (answer(S)) 

возился с кодом немного и обнаружил, что функция Английскость() не дает правильные коэффициенты в python3.2 (Это всегда дает 0). Я не могу понять, что я делаю неправильно.

+0

Я думаю, что автор библиотеки может быть в состоянии ответить на этот вопрос в лучшую сторону. Кажется, проблема с библиотекой pycrypto. – CrakC

+0

@CrakC Я не думаю, что это проблема с библиотекой pycrypto. Как показано выше, значение «i», для которого оно дает желаемый результат, равно «88». Я открыл интерпретатор Python3.2, и strxor_c (S, 88) дает мне правильную строку вывода («Cooking MC's like pound of bacon»). Кроме того, согласно официальному сайту, pycrypto работает для Python2.1 через Python3.3. – BigFatProgrammer

ответ

0

Эта линия является проблематичной

coefficient = sum(math.sqrt(FREQUENCY_TABLE.get(char, 0) * y/total_characters) for char,y in c.items()) 

В Python3, char является ога характера - не фактический характер, как в python2. Сравните:

$ python2 
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> [char for char in b'foobar'] 
['f', 'o', 'o', 'b', 'a', 'r'] 
>>> 

$ python3 
Python 3.4.3 (default, Jul 28 2015, 18:20:59) 
[GCC 4.8.4] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> [char for char in b'foobar'] 
[102, 111, 111, 98, 97, 114] 

Один быстрый (некрасиво) исправление

coefficient = sum(math.sqrt(FREQUENCY_TABLE.get(bytes([char]), 0) * y/total_characters) for char,y in c.items()) 
+0

это фактически решила проблему. Но можете ли вы рассказать мне разницу между байтами (char) и байтами ([char])? – BigFatProgrammer

+0

'bytes (char)' возвращает массив char zeros (помните, char здесь число) 'bytes (10) == b '\ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00'' –

+0

Почему он дает другой вывод для списка? что означает, что включение числа в квадратных скобках дает другое значение? – BigFatProgrammer

Смежные вопросы