struct pack 打印字符串而不是二进制值
struct pack printing a string instead of binary value
为什么我的 struct.pack 打印的是字符串而不是二进制流?
var = struct.pack('hhl3sf', 1, 2, 3, 'm6y', 2.7)
print repr(var)
输出为:
'\x01\x00\x02\x00\x03\x00\x00\x00m6y\x00\xcd\xcc,@'
'm6y' 应该打印成 \x6d\x36\x79 吗?如果没有,我如何直接从 pack 打印它作为她或只是普通的二进制文件?
为什么 char @ 打印在最后?谢谢
我尝试将所有值转换为 ascii,然后以十六进制打印它们。
还有 运行 binascii.hexlify。
它们都有效,但我想知道为什么 pack 没有自动执行此操作。谢谢
map(lambda c: ord(c), var)
map(lambda i: hex(i), map(lambda c: ord(c), var))
print 'Packed value : ', binascii.hexlify(var)
Python 的默认表示在可能的情况下将字节串打印为 ascii 字符,如果不可能则仅作为 \x
转义。
通常希望 'm6y'
打印为 \x6d\x36\x79
,但事实并非如此。
如果你想看到变量全部显示为十六进制,那么你需要自己做。例如:
>>> "".join("{0:02x}".format(b) for b in var)
'01000200030000006d367900cdcc2c40'
>>> print("".join("\0x{0:02x}".format(b) for b in var))
[=10=]x01[=10=]x00[=10=]x02[=10=]x00[=10=]x03[=10=]x00[=10=]x00[=10=]x00[=10=]x6d[=10=]x36[=10=]x79[=10=]x00[=10=]xcd[=10=]xcc[=10=]x2c[=10=]x40
具体如何查看取决于您。字节串通常是 ascii 字符,默认情况下 b"Hello world"
显示为
[=11=]x48[=11=]x65[=11=]x6c[=11=]x6c[=11=]x6f[=11=]x20[=11=]x77[=11=]x6f[=11=]x72[=11=]x6c[=11=]x64
不友好。
字符串打印问题
在 [SO]: Python struct.pack() behavior (@CristiFati's answer) 中(开头的某处),我尝试简要解释该行为。基本上,当向用户显示一些内存内容时,如果某个字节有对应的可打印字符,则使用该字符(注意,这只是为了演示,它不影响内存内容)。
如果您想绕过此行为,则必须手动执行(有多种方法 - 我不打算坚持使用它们)。但请记住,这样做后,生成的字符串将不等同于原始字符串:
>>> b0 = b"\x41"
>>> b0
b'A'
>>> len(b0)
1
>>>
>>> b1 = "".join(("\x{:02X}".format(c) for c in b0))
>>> b1
'\x41'
>>> len(b1)
4
结束char问题
正在发布 [Python 3.Docs]: struct - Interpret bytes as packed binary data 页面。
将问题分解为更简单的问题并分别解决每个问题:
'@' char (0x40) 在结果字符串的末尾:它是 2.7 的一部分 :
>>> import struct
>>>
>>> s0 = struct.pack(b"f", 2.7)
>>> s0
b'\xcd\xcc,@'
>>> len(s0)
4
>>>
>>> s1 = struct.pack(b"f", 1.7)
>>> s1
b'\x9a\x99\xd9?'
>>> len(s1)
4
我认为混淆是由最后一个'\x00'字节(var[-5]
):
>>> struct.pack(b"3sI", b"ABC", 0xFFFFFFFF)
b'ABC\x00\xff\xff\xff\xff'
>>>
>>> struct.pack(b"@3sI", b"ABC", 0xFFFFFFFF)
b'ABC\x00\xff\xff\xff\xff'
>>>
>>> struct.pack(b"=3sI", b"ABC", 0xFFFFFFFF)
b'ABC\xff\xff\xff\xff'
>>>
>>>
>>> struct.pack(b"4sI", b"ABCD", 0xFFFFFFFF)
b'ABCD\xff\xff\xff\xff'
>>>
>>> struct.pack(b"1sI", b"A", 0xFFFFFFFF)
b'A\x00\x00\x00\xff\xff\xff\xff'
>>>
>>> struct.pack(b"1sH", b"A", 0xFFFF)
b'A\x00\xff\xff'
>>>
>>> struct.pack(b"1sB", b"A", 0xFF)
b'A\xff'
>>>
>>> struct.pack(b"1sd", b"A", 2.7)
b'A\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\x05@'
从上面的例子可以看出,和我们的floatnumber没有任何关系,而是和前面的字符串有关,这是 alignment 的问题(对于 float 是 4 字节)。检查 [Wikipedia]: Data structure alignment 了解更多详情
为什么我的 struct.pack 打印的是字符串而不是二进制流?
var = struct.pack('hhl3sf', 1, 2, 3, 'm6y', 2.7)
print repr(var)
输出为:
'\x01\x00\x02\x00\x03\x00\x00\x00m6y\x00\xcd\xcc,@'
'm6y' 应该打印成 \x6d\x36\x79 吗?如果没有,我如何直接从 pack 打印它作为她或只是普通的二进制文件? 为什么 char @ 打印在最后?谢谢
我尝试将所有值转换为 ascii,然后以十六进制打印它们。 还有 运行 binascii.hexlify。 它们都有效,但我想知道为什么 pack 没有自动执行此操作。谢谢
map(lambda c: ord(c), var)
map(lambda i: hex(i), map(lambda c: ord(c), var))
print 'Packed value : ', binascii.hexlify(var)
Python 的默认表示在可能的情况下将字节串打印为 ascii 字符,如果不可能则仅作为 \x
转义。
通常希望 'm6y'
打印为 \x6d\x36\x79
,但事实并非如此。
如果你想看到变量全部显示为十六进制,那么你需要自己做。例如:
>>> "".join("{0:02x}".format(b) for b in var)
'01000200030000006d367900cdcc2c40'
>>> print("".join("\0x{0:02x}".format(b) for b in var))
[=10=]x01[=10=]x00[=10=]x02[=10=]x00[=10=]x03[=10=]x00[=10=]x00[=10=]x00[=10=]x6d[=10=]x36[=10=]x79[=10=]x00[=10=]xcd[=10=]xcc[=10=]x2c[=10=]x40
具体如何查看取决于您。字节串通常是 ascii 字符,默认情况下 b"Hello world"
显示为
[=11=]x48[=11=]x65[=11=]x6c[=11=]x6c[=11=]x6f[=11=]x20[=11=]x77[=11=]x6f[=11=]x72[=11=]x6c[=11=]x64
不友好。
字符串打印问题
在 [SO]: Python struct.pack() behavior (@CristiFati's answer) 中(开头的某处),我尝试简要解释该行为。基本上,当向用户显示一些内存内容时,如果某个字节有对应的可打印字符,则使用该字符(注意,这只是为了演示,它不影响内存内容)。
如果您想绕过此行为,则必须手动执行(有多种方法 - 我不打算坚持使用它们)。但请记住,这样做后,生成的字符串将不等同于原始字符串:
>>> b0 = b"\x41" >>> b0 b'A' >>> len(b0) 1 >>> >>> b1 = "".join(("\x{:02X}".format(c) for c in b0)) >>> b1 '\x41' >>> len(b1) 4
结束char问题
正在发布 [Python 3.Docs]: struct - Interpret bytes as packed binary data 页面。
将问题分解为更简单的问题并分别解决每个问题:
'@' char (0x40) 在结果字符串的末尾:它是 2.7 的一部分 :
>>> import struct >>> >>> s0 = struct.pack(b"f", 2.7) >>> s0 b'\xcd\xcc,@' >>> len(s0) 4 >>> >>> s1 = struct.pack(b"f", 1.7) >>> s1 b'\x9a\x99\xd9?' >>> len(s1) 4
我认为混淆是由最后一个'\x00'字节(
var[-5]
):>>> struct.pack(b"3sI", b"ABC", 0xFFFFFFFF) b'ABC\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"@3sI", b"ABC", 0xFFFFFFFF) b'ABC\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"=3sI", b"ABC", 0xFFFFFFFF) b'ABC\xff\xff\xff\xff' >>> >>> >>> struct.pack(b"4sI", b"ABCD", 0xFFFFFFFF) b'ABCD\xff\xff\xff\xff' >>> >>> struct.pack(b"1sI", b"A", 0xFFFFFFFF) b'A\x00\x00\x00\xff\xff\xff\xff' >>> >>> struct.pack(b"1sH", b"A", 0xFFFF) b'A\x00\xff\xff' >>> >>> struct.pack(b"1sB", b"A", 0xFF) b'A\xff' >>> >>> struct.pack(b"1sd", b"A", 2.7) b'A\x00\x00\x00\x00\x00\x00\x00\x9a\x99\x99\x99\x99\x99\x05@'
从上面的例子可以看出,和我们的floatnumber没有任何关系,而是和前面的字符串有关,这是 alignment 的问题(对于 float 是 4 字节)。检查 [Wikipedia]: Data structure alignment 了解更多详情