【问题标题】:breaking a 32-bit number into individual fields将 32 位数字分解为单个字段
【发布时间】:2010-01-26 12:43:40
【问题描述】:

在 python 中是否有一种快速的方法可以快速将 32 位变量(例如,a1a2a3a4)拆分为 a1a2a3a4?我已经通过将值更改为十六进制然后拆分它来完成它,但是这样做似乎是浪费时间int->string->int

【问题讨论】:

  • 请解释一下您认为 Python 的“32 位变量”是什么。如果你假设它的值是无符号的,那么就这么说吧。如果不是,请说明您想要的结果。
  • 我猜它是无符号的,因为任何值都没有理由为负。我的意思是 a1,a2 就像一个大变量/字符串中的索引。我应该放 x1x2x3x4,但这同样有效。我正在尝试编写 CAST128,其中一部分临时字节存储在 x1x2x3...x16、z1z2...z16 中。我如何一次操作 4 个并更新它们?

标签: python


【解决方案1】:

在 Python 中并没有真正意义上的 32 位变量。你是这个意思吗?

x = 0xa1a2a3a4
a4 = int(x & 0xff)
a3 = int((x >> 8) & 0xff)
a2 = int((x >> 16) & 0xff)
a1 = int(x >> 24)

正如 SilentGhost 指出的那样,您不需要 int 转换,因此您可以这样做:

a4 = x & 0xff
a3 = (x >> 8) & 0xff
a2 = (x >> 16) & 0xff
a1 = x >> 24

请注意,在旧版本的 Python 中,如果 x 的值大于 0x7fffffff,则第二个版本将返回 longs,否则返回 int。第一个版本总是返回 int。在较新版本的 Python 中,这两种类型是 unified,因此您不必担心这个细节。

【讨论】:

  • 你为什么要做int转换?
  • SilentGhost:因为他可能正在使用 Python 2.x,并且他可能希望结果为 int,而不是 long。这没有必要,但也不会受到伤害。如果您愿意,欢迎您省略 int 转换。
  • Silent Ghost:我现在已经发布了两个版本。 :)
【解决方案2】:

使用按位运算。

例如:

myvar = 0xcdf100cd
a0 = myvar & 0xff
a1 = (myvar >> 8) & 0xff
a2 = (myvar >> 16) & 0xff
a3 = (myvar >> 24) & 0xff

&0xff 保留值的低 8 位并将其余值归零,而位移运算符 (>>) 用于将您提取的字节移位到这些低 8 位。

【讨论】:

    【解决方案3】:

    标准库模块struct 做了很短的工作:

    >>> import struct
    >>> x = 0xa1a2a3a4
    >>> struct.unpack('4B', struct.pack('>I', x))
    (161, 162, 163, 164)
    

    '>I' 格式的“打包”使x 按大端顺序变成一个 4 字节的字符串,然后可以立即将其“解包”成四个无符号字节大小的值,格式为 '4B'。轻松愉快。

    【讨论】:

    • 我知道这是一篇旧文章,但对于现在正在看这个的任何人来说——这在 Python 3 中不起作用。TypeError: 'int' 不支持缓冲区接口
    • @ThatAintWorking 对不起?仅当您将整数传递给 struct.unpack() 时才会在此处引发 TypeError (因此,你知道,错误文本提到了一个 int ...),但是如果您注意到,这个答案永远不会发生这种情况,因为 struct.pack()总是返回一个字符串......所以它按预期工作 100%,即使在 Python 3 上也是如此。我假设你放弃了嵌套包并试图将一个整数直接传递给 struct.unpack() 而没有注意到?
    • M. I. Wright,时间太长了。我什至不记得当我得到这个时我在做什么,但你可能是对的,我传递的是一个 int 而不是一个字符串。
    【解决方案4】:

    有点晚了,但我通常会这样做:

    hexnum = 0xa1a2a3a4
    bytes = []
    while (hexnum > 0):
        bytes.insert(0, hexnum & 0xff)
        hexnum >>= 8
    

    不确定它是否比解包更有效(可能不是由于使用了 list.insert())。

    【讨论】:

      猜你喜欢
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 2011-12-29
      • 2010-12-19
      • 1970-01-01
      • 2015-09-30
      • 2019-05-17
      相关资源
      最近更新 更多