Python - 尝试处理文件的位

发布于 2025-01-02 03:20:14 字数 258 浏览 2 评论 0原文

我最近开始学习Python,我选择通过尝试解决一个我觉得有趣的问题来学习东西。这个问题是获取一个文件(无论是否为二进制)并使用一种简单的方法对其进行加密,例如将其中的每个“1001 0001”替换为“0010 0101”,反之亦然。

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

提前致谢!

I have very recently started to learn Python, and I chose to learn things by trying to solve a problem that I find interesting. This problem is to take a file (binary or not) and encrypt it using a simple method, something like replacing every "1001 0001" in it with a "0010 0101", and vice-versa.

However, I didn't find a way to do it. When reading the file, I can create an array in which each element contains one byte of data, with the read() method. But how can I replace this byte with another one, if it is one of the bytes I chose to replace, and then write the resulting information into the output encrypted file?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏见 2025-01-09 03:20:14

要交换字节 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))

To swap bytes 10010001 and 00100101:

#!/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))
无人问我粥可暖 2025-01-09 03:20:14

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

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

read() returns an immutable string, so you'll first need to convert that to a list of characters. Then go through your list and change the bytes as needed, and finally join the list back into a new string to write to the output file.

filedata = f.read()
filebytes = list(filedata)
for i, c in enumerate(filebytes):
    if ord(c) == 0x91:
        filebytes[i] = chr(0x25)
newfiledata = ''.join(filebytes)
难如初 2025-01-09 03:20:14

按照亚伦的回答,一旦有了字符串,您还可以使用 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 字符串

Following Aaron's answer, once you have a string, then you can also use translate or replace:

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'

Docs: Python string.

假装爱人 2025-01-09 03:20:14

我对这面有些相关的文字墙感到抱歉——我只是处于教学心情。

如果你想优化这样的操作,我建议使用numpy。优点是整个翻译操作是通过单个 numpy 操作完成的,并且这些操作是用 C 编写的,因此它的速度与使用 python 获得的速度一样快。

在下面的示例中,我只是使用 XOR 每个字节与 0b11111111查找表——第一个元素是0b0000000的翻译,第二个元素是0b00000001的翻译,第三个元素是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

当然,没有使用 频率分析。但正如您所知,使用一次性密码本进行的加密是牢不可破的,只要因为垫子是安全的。此修改后的脚本使用一次性密码本进行加密或解密(您必须自己创建它,存储到文件中,并以某种方式(存在问题)安全地传输到消息的预期收件人):

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 中的三行(加上两行导入)快速且牢不可破的加密。

I'm sorry about this somewhat relevant wall of text -- I'm just in a teaching mood.

If you want to optimize such an operation, I suggest using numpy. The advantage is that the entire translation operation is done with a single numpy operation, and those are written in C, so it is about as fast as you can get it using python.

In the below example I simply XOR every byte with 0b11111111 using a lookup table -- first element is the translation of 0b0000000, the second the translation of 0b00000001, third 0b00000010, and so on. By altering the lookup table, you can do any kind of translation that does not change within the file.

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])

To highlight the simplicity of it all I've done no argument checking. Invoke script like this:

python name_of_script.py input_file.txt output_file.txt

To directly answer your question, if you want to swap 0b10010001 and 0b00100101, you replace the lookup_table = ... line with this:

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

Of course there is no lookup table encryption that isn't easily broken using frequency analysis. But as you may know, encryption using a one-time pad is unbreakable, as long as the pad is safe. This modified script encrypts or decrypts using a one-time pad (which you'll have to create yourself, store to a file, and somehow (there's the rub) securely transmit to the intended recipient of the message):

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

Example usage (linux):

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

Recipient then does:

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

Viola! Fast and unbreakable encryption with three lines (plus two import lines) in python.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文