Python - 试图处理文件的位

时间:2012-02-02 20:16:18

标签: python encryption bits

我最近开始学习Python,我选择通过尝试解决我感兴趣的问题来学习。这个问题是采用一个文件(二进制或不二进制)并使用一种简单的方法对其进行加密,例如用“0010 0101”替换其中的每个“1001 0001”,反之亦然。

但是,我找不到办法。在读取文件时,我可以使用read()方法创建一个数组,其中每个元素包含一个字节的数据。但是,如果它是我选择替换的字节之一,然后将结果信息写入输出加密文件,我怎么能用另一个字节替换这个字节呢?

提前致谢!

4 个答案:

答案 0 :(得分:2)

交换字节1001000100100101

#!/usr/bin/env python
import string

a, b = map(chr, [0b10010001, 0b00100101])
translation_table = string.maketrans(a+b, b+a) # swap a,b

with open('input', 'rb') as fin, open('output', 'wb') as fout:
     fout.write(fin.read().translate(translation_table))

答案 1 :(得分:1)

read()返回一个不可变的字符串,因此您首先需要将其转换为字符列表。然后浏览列表并根据需要更改字节,最后将列表重新加入到新字符串中以写入输出文件。

filedata = f.read()
filebytes = list(filedata)
for i, c in enumerate(filebytes):
    if ord(c) == 0x91:
        filebytes[i] = chr(0x25)
newfiledata = ''.join(filebytes)

答案 2 :(得分:0)

按照Aaron的回答,一旦你有一个字符串,你也可以使用translatereplace

In [43]: s = 'abc'

In [44]: s.replace('ab', 'ba')
Out[44]: 'bac'

In [45]: tbl = string.maketrans('a', 'd')

In [46]: s.translate(tbl)
Out[46]: 'dbc'

文档:Python string

答案 3 :(得分:0)

我对这个有点相关的文本墙感到抱歉 - 我只是在教学中。

如果您想优化此类操作,建议您使用numpy。优点是整个翻译操作只需要一个numpy操作,并且用C语言编写,所以它的速度和你使用python一样快。

在下面的示例中,我只使用0b11111111使用查找表XOR frequency analysis每个字节 - 第一个元素是0b0000000的翻译,第二个元素是0b00000001的翻译,第三个0b00000010,等等。通过更改查找表,您可以执行在文件中不会更改的任何类型的转换。

import numpy as np
import sys

data = np.fromfile(sys.argv[1], dtype="uint8")
lookup_table = np.array(
    [i ^ 0xFF for i in range(256)], dtype="uint8")
lookup_table[data].tofile(sys.argv[2])

为了突出它的简单性,我没有做任何参数检查。像这样调用脚本:

python name_of_script.py input_file.txt output_file.txt

要直接回答您的问题,如果您要交换0b100100010b00100101,请将lookup_table = ...行替换为:

lookup_table = np.array(range(256), dtype="uint8")
lookup_table[0b10010001] = 0b00100101
lookup_table[0b00100101] = 0b10010001

当然,没有使用one-time pad不容易破解的查找表加密。但正如您所知,只要垫是安全的,使用{{3}}进行加密是不可破解的。这个修改后的脚本使用一次性密码加密或解密(您必须自己创建,存储到文件,并以某种方式(有摩擦)安全地传输到消息的预期接收者):

data = np.fromfile(sys.argv[1], dtype="uint8")
pad = np.fromfile(sys.argv[2], dtype="uint8")
(data ^ pad[:len(data)]).tofile(sys.argv[3])

示例用法(linux):

$ dd if=/dev/urandom of=pad.bin bs=512 count=5
$ python pytrans.py pytrans.py pad.bin encrypted.bin

收件人然后:

$ python pytrans.py encrypted.bin pad.bin decrypted.py

中提琴!在python中使用三行​​(加上两个导入行)进行快速且牢不可破的加密。