2013-04-16 6 views
2

Я пытаюсь сделать простой скрипт шифрования в python. Я просто хочу использовать шифрование XOR для двоичных файлов. Мой сценарий в основном выглядит следующим образом:Xor шифрование в двоичном файле в python

def xor_c (a): 
    v='' 
    for p in a: 
     v += chr((ord(p)^0xA8)) 
    return v 

Целью этого является только для шифрования каждого байта в отдельности. Это должно работать, но все попытки, которые я сделал, не удались.

я впервые попробовал с:

handler = open("file",'r') 
handler2 = open("output",'w') 
contents = handler.read() 
handler2.write(xor_c(xor_c(contents))) 

Но после выполнения этих двух файлов file и output были разными. Поскольку входной файл был двоичный файл (то, что я хочу), я изменил сценарий:

handler = open("file",'rb') 
handler2 = open("output",'wb') 
contents = handler.read() 
handler2.write(xor_c(xor_c(contents))) 

Но это не изменило ничего. Как бы то ни было, некоторые пары байтов преобразуются в один байт на выходе (возможно, потому, что символы не ascii, но это не должно происходить с двоичным режимом ...). . Кроме того, последний байт выходе 0xA8 (логически получил от превращения \0 в конце входного файла С учетом этого я также изменил функцию xor_c на:

def xor_c (a): 
    v='' 
    for p in a: 
     v += chr((ord(p)^0xA8)) 
    return v[:-1]+'\0' 

Чтобы убедиться, что последний символ всегда будет \0, но это не работает.

Любые предложения? замечания? советы?

Благодаря

+0

Ваш код отлично работает на моем компьютере, а 'handler2' содержит точно такие же данные, как' handler'. Кстати: ваш 'xor_c' очень неэффективен. Я бы создал таблицу переводов и вместо этого использовал 'str.translate'. – Bakuriu

+0

Если некоторые символы представлены более чем одним байтом, это может быть файл unicode. Python 2.x и 3.x требуют разных подходов, поэтому было бы полезно указать, какая версия вы используете. – guidot

+0

@guidot: Я использую python 2.7. @Bakuriu: Я не вижу, как я могу использовать 'str.translate()' для воссоздания, почему я хочу. – ibi0tux

ответ

1

(Жаль, что я неправильно понял вопрос в первой)

Я думаю, что проблема может заключаться в v инициализации: v не должно быть string, но bytearray

v = bytearray() 

У меня нет инструментов, чтобы проверить здесь.

+0

Я пробовал с bytearray(), есть изменения. Некоторые байты теперь одобрены, но некоторые другие все еще неверно преобразованы. Это странно ... Я видел в pydoc, что 'ord()' способен преобразовывать символы, отличные от ASCII. Вы знаете, возможно ли, что он пытается конвертировать несколько байтов одновременно (даже в двоичном режиме)? – ibi0tux

2

Если вы просто хотите сделать xor, вам не нужны chr() и ord(), если вы используете bytearray.

Фактически, ваша функция становится однострочным;

def xor_c(a): 
    return bytearray([b^0xA8 for b in bytearray(a)]) 

И это прекрасно работает

In [4]: xor_c('Test') 
Out[4]: bytearray(b'\xfc\xcd\xdb\xdc') 

In [5]: r1 = xor_c('Test') 

In [6]: r2 = xor_c(r1) 

In [7]: r2 
Out[7]: bytearray(b'Test') 

Существует что-то не так в ваших примерах. Это вход: input image

это ваш выход после двойного исключающего: output

Обратите внимание, что в некоторых местах «'» преобразуется в iили в j. Это не возможно с простой двойной xor.

Вы уверены, что используете код, указанный мной выше? Потому что, если я запускаю его на бинарный файл дважды данные исключающих-эды равно к исходным данным:

In [1]: def xor_c(a, c=0xA8): 
    ...:  return bytearray([b^c for b in bytearray(a)]) 
    ...: 

In [2]: with open('foo.gz', 'rb') as inf: 
    data = inf.read() 
    ...:  

In [3]: data2 = xor_c(xor_c(data)) 

In [4]: cmp(data, data2) 
Out[4]: 0 

Когда я пишу данные на диск и сравнить его, файлы идентичны тоже:

In [5]: with open('foo2.gz', 'wb') as outf: 
    outf.write(data2) 
    ...:  

> ll foo* 
-rw-r--r-- 1 rsmith rsmith - 4049792 Apr 16 13:15 foo2.gz 
-rw-r--r-- 1 rsmith rsmith - 4049792 Apr 16 12:39 foo.gz 
> diff foo* 
+0

У меня все еще такая же проблема. Некоторые символы не совпадают на входе и выходе. – ibi0tux

+0

@ ibi0tux: Можете ли вы добавить пример на свой вопрос? Это должно быть то же самое. –

+0

Вот два скриншота, которые я сделал, показывая содержимое с 'less'. Первый - это входной файл, а второй - выходной файл. (входной файл: [ссылка] (http://www.mirari.fr/MyeY), выходной файл: [ссылка] (http://www.mirari.fr/igDI)) – ibi0tux

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