【问题标题】:copy 3 byte char to int将 3 字节 char 复制到 int
【发布时间】:2012-08-01 07:30:33
【问题描述】:

我有一个包含 3 个字节的字节流,我必须将其转换为无符号整数 32。在 C 中,我只需使用 bzero 将整数的内存区域清零,然后从流中复制内存,类似于

char* stream = ...;
Uint32 myInt;
bzero(myInt,4);
memcopy(myInt, stream[0], stream[3])

问题:

我将如何在 Python 中做到这一点?

干杯

【问题讨论】:

标签: python c char int


【解决方案1】:

即使在 C 语言中,您也不应该使用 memcpy 进行二进制反序列化,因为它不处理二进制表示,即字节序、符号等。将二进制值从流中的固定表示显式解码为平台的本机表示。

在 Python 中,您会从流中读取字节,根据字节序填充它们,然后使用 struct 解压缩它们:

chunk = fileobj.read(3)
# decode bytes as little-endian, signed integer
chunk += '\x00'
number = struct.unpack('<i', chunk)

fileobj是一个类文件对象,代表打开的流,即用open(filename, 'rb')打开的文件。

【讨论】:

  • 带有memcpy 的提问者代码非常适合从流中反序列化网络顺序的 32 位无符号整数。 读取值之后处理字节序,这就是ntohl 的用途。如果任一端都是非 2 的补码,则同样的技巧对有符号值不起作用。
  • 谢谢,这正是我想要的。
【解决方案2】:

你试过了吗:

myInt = (ord (myStr[0]) * 256 + ord (myStr[1])) * 256 + ord (myStr[2])

以下程序:

myStr = "abc"
myInt = ord (myStr[0]) * 65536 + ord (myStr[1]) * 256 + ord (myStr[2])
print myInt

按预期输出6382179

'a' (97) * 65536 = 6356992
'b' (98) *   256 =   25088
'c' (99) *     1 =      99
                   -------
                   6382179

当然,这是假设字符串采用大端格式。对于 little-endian,其中最重要的八位字节是字符串中的 第三个​​,您可以反转字符串索引(2, 1, 0 而不是 0, 1, 2)。

【讨论】:

    【解决方案3】:

    正如@paxdiablo 所说,ord 是解决方案。这是&lt;&lt; 的解决方案,它可以更熟悉C:

    sum([ord(c) << 8 * i for i, c in enumerate(s) ])
    

    【讨论】:

      猜你喜欢
      • 2016-03-05
      • 1970-01-01
      • 2014-04-04
      • 2011-11-11
      • 1970-01-01
      • 2016-03-03
      • 2013-08-20
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多