我想将二进制文件(例如jpg,mp3等)转换为Web安全文本,然后再转换为二进制数据。我已经研究了几个模块,我认为我非常接近,但我一直在弄乱数据。
在查看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_base64
和57长的二进制数据块。我把每个块转换成一个字符串,将它们连接在一起,然后转换回a2b_base64
并再次腐败。
有人可以帮忙吗?我对所有复杂的字节和文件格式都不是很了解。我在Windows上使用Python,如果这对\r\n
内容产生影响
答案 0 :(得分:1)
您应该使用base64编码而不是quoted printable。使用b2a_base64()
和a2b_base64()
。
对于像图片这样的二进制数据,引用的可打印要大得多。在此编码中,每个二进制(非字母数字字符)代码都将更改为=HEX
。它可用于主要由电子邮件主题等字母数字组成的文本。
对于主要的二进制数据,Base64要好得多。它需要6个第一个字节的位,然后是第1个字节的最后2位和第2个字节的4个位。它可以通过编码文本末尾的=
填充来识别(有时使用其他字符)。
作为一个例子,我拿了271 700字节的.jpeg。在qp中它是627 857 b,而在base64中它是362 269字节。 qp的大小取决于数据类型:仅为字母的文本不会更改。 base64的大小为orig_size * 8 / 6
。
答案 1 :(得分:1)
您的文档参考适用于Python 3.0.1。使用Python 3.0没有充分的理由。你应该使用3.2或2.7。你究竟在用什么?
建议:(1)将bytes
更改为raw_bytes
,以避免与bytes
== raw_bytes
的{{1}}内置(2)检查混淆在您的测试脚本(3)中,当您的测试应该使用quoted-printable时,二进制数据的效率非常低;改为使用base64。
更新:Base64编码为每3个输入字节产生4个输出字节。你的base64代码不适用于56字节的块,因为56不是3的整数倍;每个块被填充到3的倍数。然后你加入块并尝试解码,这保证不起作用。
你的分块循环会写得更好:
bytes_back
无论如何,分块相当缓慢而毫无意义;只需output_string = ''.join(
b2a_base64(raw_bytes[i:i+57]) for i in xrange(0, xrange(len(raw_bytes), 57)
)
答案 2 :(得分: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
对我来说似乎最直接 - 只需将其设为一个字符串,处理它并将其转换回来。
答案 3 :(得分:-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