0

我想将二进制文件(例如 jpg、mp3 等)转换为网络安全文本,然后再转换回二进制数据。我研究了一些模块,我认为我真的很接近,但我不断收到数据损坏。

在查看了binascii的文档后,我想到了这个:

from binascii import *
raw_bytes = open('test.jpg','rb').read()
text = b2a_qp(raw_bytes,quotetabs=True,header=False)
bytesback = a2b_qp(text,header=False)
f = open('converted.jpg','wb')
f.write(bytesback)
f.close()

当我尝试打开时,converted.jpg我得到数据损坏:-/

我还尝试使用b2a_base6457 长的二进制数据块。我把每个块,转换成一个字符串,把它们连接在一起,然后再转换回来,a2b_base64又被破坏了。

任何人都可以帮忙吗?我对字节和文件格式的所有复杂性并不是非常了解。\r\n如果这对这些东西有影响,我在 Windows 上使用 Python

4

4 回答 4

1

您的文档参考适用于 Python 3.0.1。没有充分的理由使用 Python 3.0。您应该使用 3.2 或 2.7。你到底在用什么?

建议:(1)更改bytesraw_bytes避免与bytes内置的混淆(2)在测试脚本中检查raw_bytes== bytes_back(3)虽然您的测试应该使用quoted-printable,但对于二进制数据来说效率非常低;改用 base64。

更新:Base64 编码为每 3 个输入字节产生 4 个输出字节。您的 base64 代码不适用于 56 字节块,因为 56 不是 3 的整数倍;每个块被填充为 3 的倍数。然后你加入块并尝试解码,这保证不会工作。

你的分块循环会更好地写成:

output_string = ''.join(
    b2a_base64(raw_bytes[i:i+57]) for i in xrange(0, xrange(len(raw_bytes), 57)
    )

在任何情况下,分块都是相当缓慢且毫无意义的。做就是了b2a_base64(raw_bytes)

于 2011-10-23T20:08:49.800 回答
1

您应该使用 base64 编码而不是引用的可打印。使用b2a_base64()a2b_base64()

对于图片等二进制数据,引用的可打印内容要大得多。在此编码中,每个二进制(非字母数字字符)代码都更改为=HEX. 它可用于主要由字母数字组成的文本,如电子邮件主题。

Base64 对于主要是二进制数据要好得多。它占用第一个字节的 6 位,然后是第一个字节的最后 2 位和从第二个字节开始的 4 位。等等。它可以通过=在编码文本末尾的填充来识别(有时使用其他字符)。

作为示例,我采用了 271 700 字节的 .jpeg。在 qp 中为 627 857 b,而在 base64 中为 362 269 字节。qp 的大小取决于数据类型:只有字母的文本不会改变。base64 的大小是orig_size * 8 / 6.

于 2011-10-23T19:48:17.797 回答
1

你的代码看起来很复杂。尝试这个:

#!/usr/bin/env python

from binascii import *
raw_bytes = open('28.jpg','rb').read()
i = 0
str_one = b2a_base64(raw_bytes) # 1
str_list = b2a_base64(raw_bytes).split("\n") #2

bytesBackAll = a2b_base64(''.join(str_list)) #2
print bytesBackAll == raw_bytes #True #2

bytesBackAll = a2b_base64(str_one) #1
print bytesBackAll == raw_bytes #True #1

#1用和标记的线#2代表彼此的替代品。#1对我来说似乎最简单 - 只需将其设为一个字符串,对其进行处理并将其转换回来。

于 2011-10-23T22:12:04.233 回答
-2

@PMC 从问题中复制的答案:

这是有效的:

from binascii import *
raw_bytes = open('28.jpg','rb').read()
str_list = []
i = 0
while i < len(raw_bytes):
    byteSegment = raw_bytes[i:i+57]
    str_list.append(b2a_base64(byteSegment))
    i += 57
bytesBackAll = a2b_base64(''.join(str_list))
print bytesBackAll == raw_bytes #True

谢谢你们的帮助。我不知道为什么这会以 [0:56] 而不是 [0:57] 失败,但我将把它作为练习留给读者:P

于 2011-10-24T05:44:31.447 回答