0

我正在尝试在 Python 3.3 中使用 MIMEApplication 对二进制文件进行编码,作为多部分 MIME HTTP POST 的一部分。我有一个问题,字符 0x0d 被重新解释为换行符 0xa,尽管所有内容都设置为二进制字节。

这是一个最小的测试场景,其中包含一个带有 0x0d 的二进制字符串,但被误解了:

from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io

app = MIMEApplication(b'Q\x0dQ', _encoder=encode_noop)
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app)
for i in b.getvalue()[-3:]:
    print("%02x " % i, end="")
print()

输出是:51 0a 51应该是什么时候51 0d 51

请注意,这是为多部分 http POST 消息生成二进制部分。

4

2 回答 2

1

尝试以下操作(不指定编码器,使用默认 base64 编码器):

import email
from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io

app = MIMEApplication(b'Q\x0dQ')
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app)
msg = email.message_from_bytes(b.getvalue())
assert msg.get_payload(decode=True) == b'Q\x0dQ'
于 2013-09-25T19:02:29.713 回答
-1

我可以通过在 MIMEApplication 内容中放置一个虚拟“标记”来解决我的问题,然后在生成 MIME 消息后替换为真正的二进制文本:

from email.encoders import encode_noop
from email.generator import BytesGenerator
from email.mime.application import MIMEApplication
import io

# Actual binary "file" I want to encode (in real life, this is a file read from disk)
bytesToEncode = b'Q\x0dQ'

# unique marker that we can find and replace after message generation
binarymarker = b'GuadsfjfDaadtjhqadsfqerasdfiojBDSFGgg'

app = MIMEApplication(binarymarker, _encoder=encode_noop)
b = io.BytesIO()
g = BytesGenerator(b)
g.flatten(app, linesep='\r\n')  # linesep for HTTP-compliant header line endings

# replace the marker with the actual binary data, then you have the output you want!
body = b.getvalue().replace(binarymarker, bytesToEncode)

在此之后,body具有我想要的值,而不会弄乱二进制字节:

b'Content-Type: application/octet-stream\r\nMIME-Version: 1.0\r\n\r\nQ\rQ'

对于多部分消息,您只需先组装多部分消息,然后在最后执行 replace()。

于 2013-09-26T16:31:52.047 回答