为了账号安全,请及时绑定邮箱和手机立即绑定

python 打包/解包编号指定字节数

python 打包/解包编号指定字节数

泛舟湖上清波郎朗 2022-09-27 10:00:41
我正在尝试将Python中的int数字(> = 0 > <2 ^ 32)转换为4字节无符号int表示并返回。据我所知,struct.pack中给出的文档大小是标准的,但不能保证大小。我如何确保我得到4个字节?我发现使用ctypes的一种方式:byte_repr=bytes(ctypes.c_uint32(data))这是最悍亵的吗?回去的路是什么(对于这个或任何其他解决方案)?
查看完整描述

2 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

类型和具有您需要的方法。intbytes


请注意,我从类中调用,但它可以从实例对象调用:from_bytesintint


>>> a = 2**32-1

>>> a.to_bytes(4, 'little')

b'\xff\xff\xff\xff'

>>> b = a.to_bytes(4, 'little')

>>> c = int.from_bytes(b, 'little')

>>> c

4294967295

>>> a

4294967295

>>>


查看完整回答
反对 回复 2022-09-27
?
慕村225694

TA贡献1880条经验 获得超4个赞

给定提到的间隔,您正在谈论无符号int
[Python 3.Docs]:结构 - 将字符串解释为打包的二进制数据可以正常工作(好吧,在 sizeof(int) == 4 的平台(编译器)上)。
由于对于绝大多数环境,上述情况是正确的,因此您可以安全地使用它(除非您确信代码将在一个陌生的平台上运行,其中用于构建Python的编译器是不同的)。

>>> import struct

>>>

>>> bo = "<"  # byte order: little endian

>>>

>>> ui_max = 0xFFFFFFFF

>>>

>>> ui_max

4294967295

>>> buf = struct.pack(bo + "I", ui_max)

>>> buf, len(buf)

(b'\xff\xff\xff\xff', 4)

>>>

>>> ui0 = struct.unpack(bo + "I", buf)[0]

>>> ui0

4294967295

>>>

>>> i0 = struct.unpack(bo + "i", buf)[0]  # signed int

>>> i0

-1

>>> struct.pack(bo + "I", 0)

b'\x00\x00\x00\x00'

>>>

>>> struct.pack(bo + "I", ui_max + 1)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

struct.error: argument out of range

>>>

>>> struct.unpack(bo + "I", b"1234")

(875770417,)

>>>

>>> struct.unpack(bo + "I", b"123")  # 3 bytes buffer

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

struct.error: unpack requires a buffer of 4 bytes

>>>

>>> struct.unpack(bo + "I", b"12345")  # 5 bytes buffer

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

struct.error: unpack requires a buffer of 4 bytes

相关(远程): [SO]:C 的最大值和最小值来自 Python 的整数

[蟒蛇 3.文档]: ctypes - 蟒蛇变体的外来函数库

>>> # Continuation of previous snippet

>>> import ctypes as ct

>>>

>>> ct_ui_max = ct.c_uint32(ui_max)

>>>

>>> ct_ui_max

c_ulong(4294967295)

>>>

>>> buf = bytes(ct_ui_max)

>>> buf, len(buf)

(b'\xff\xff\xff\xff', 4)

>>>

>>> ct.c_uint32(ui_max + 1)

c_ulong(0)

>>>

>>> ct.c_uint32.from_buffer_copy(buf)

c_ulong(4294967295)

>>> ct.c_uint32.from_buffer_copy(buf + b"\x00")

c_ulong(4294967295)

>>> ct.c_uint32.from_buffer_copy(b"\x00" + buf)  # 0xFFFFFF00 (little endian)

c_ulong(4294967040)

>>>

>>> ct.c_uint32.from_buffer_copy(buf[:-1])

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

ValueError: Buffer size too small (3 instead of at least 4 bytes)

注意:@progmatico的答案更简单,更直接,因为它不涉及内置模块以外的任何模块([Python 3.Docs]:内置类型 - 整数类型的附加方法)。作为旁注,可以使用系统字节顺序


查看完整回答
反对 回复 2022-09-27
  • 2 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号