在Python2.x中使用标准库将字节数组转换为Int

在Python2.x中使用标准库将字节数组转换为Int,python,python-3.x,python-2.7,Python,Python 3.x,Python 2.7,我熟悉使用int.from bytes()进行Python 3.x和Bytearray到十进制的转换。可能会产生下面的转换代码段。对于正整数和负整数,有没有一种方法可以使用Python2实现相同的功能 val = bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00') a = int.from_bytes(val, byteorder='big', signed=True) # print(type(a), type(val), val, a) # &l

我熟悉使用int.from bytes()进行Python 3.x和Bytearray到十进制的转换。可能会产生下面的转换代码段。对于正整数和负整数,有没有一种方法可以使用Python2实现相同的功能

val = bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00')
a = int.from_bytes(val, byteorder='big', signed=True)

# print(type(a), type(val), val, a)
# <class 'int'> <class 'bytearray'> bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00') -2083330000000000000000

Python2.7中没有内置函数来实现3.2+中的
int.from_bytes
;这就是为什么首先添加了该方法

如果您不关心处理big-endian签名整数以外的任何情况,并且更关心可读性而不是性能(因此您可以自己扩展或维护它),最简单的解决方案可能是在字节上显式循环


对于未签名的,这将很容易:

n = 0
for by in b:
    n = n * 256 + by

但要处理负数,您需要做三件事:

  • 从最高字节中去掉符号位。因为我们只关心big-endian,所以这是
    b[0]
    上的
    0x80
  • 这使得空bytearray成为一种特殊情况,所以要特别处理它
  • 最后,如果设置了符号位,则2的补码将得到结果
因此:

(在Python3中,它适用于任何一个整数的iterable。在Python2中,它包括
bytearray
bytearray
;但不包括
str


在Python 3中测试您的输入:

>>> for b in (bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00'),
...           bytearray(b'\x00'),
...           bytearray(b'\xef\xbc\xa9\xe5w\xd6\xd0\x00\x00'),
...           bytearray(b'\x10CV\x1a\x88)0\x00\x00')):
...     print(int.from_bytes(b, 'big', signed=True), int_from_bytes(b))
-2083330000000000000000 -2083330000000000000000
0 0
-300000000000000000000 -300000000000000000000
300000000000000000000 300000000000000000000
在Python 2中:

>>> for b in (bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00'),
...           bytearray(b'\x00'),
...           bytearray(b'\xef\xbc\xa9\xe5w\xd6\xd0\x00\x00'),
...           bytearray(b'\x10CV\x1a\x88)0\x00\x00')):
...     print int_from_bytes(b)
-2083330000000000000000
0
-300000000000000000000
300000000000000000000


如果这是一个瓶颈,那么几乎肯定有更快的方法来实现这一点。例如,可以通过
gmpy2
。事实上,即使将字节转换为十六进制字符串并取消验证也可能会更快,即使这项工作是原来的两倍多,如果您可以找到一种方法将这些主循环从Python移动到C。或者您可以合并调用
struct.unpack的结果,每次从
中解包8个字节,而不是逐个处理每个字节。但是这个版本应该很容易理解和维护,并且不需要stdlib之外的任何东西。

Python 2.7中没有内置函数来实现3.2+中的
int.from_bytes
;这就是为什么首先添加了该方法

如果您不关心处理big-endian签名整数以外的任何情况,并且更关心可读性而不是性能(因此您可以自己扩展或维护它),最简单的解决方案可能是在字节上显式循环


对于未签名的,这将很容易:

n = 0
for by in b:
    n = n * 256 + by

但要处理负数,您需要做三件事:

  • 从最高字节中去掉符号位。因为我们只关心big-endian,所以这是
    b[0]
    上的
    0x80
  • 这使得空bytearray成为一种特殊情况,所以要特别处理它
  • 最后,如果设置了符号位,则2的补码将得到结果
因此:

(在Python3中,它适用于任何一个整数的iterable。在Python2中,它包括
bytearray
bytearray
;但不包括
str


在Python 3中测试您的输入:

>>> for b in (bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00'),
...           bytearray(b'\x00'),
...           bytearray(b'\xef\xbc\xa9\xe5w\xd6\xd0\x00\x00'),
...           bytearray(b'\x10CV\x1a\x88)0\x00\x00')):
...     print(int.from_bytes(b, 'big', signed=True), int_from_bytes(b))
-2083330000000000000000 -2083330000000000000000
0 0
-300000000000000000000 -300000000000000000000
300000000000000000000 300000000000000000000
在Python 2中:

>>> for b in (bytearray(b'\x8f\x0f\xfd\x02\xf4\x95s\x00\x00'),
...           bytearray(b'\x00'),
...           bytearray(b'\xef\xbc\xa9\xe5w\xd6\xd0\x00\x00'),
...           bytearray(b'\x10CV\x1a\x88)0\x00\x00')):
...     print int_from_bytes(b)
-2083330000000000000000
0
-300000000000000000000
300000000000000000000


如果这是一个瓶颈,那么几乎肯定有更快的方法来实现这一点。例如,可以通过
gmpy2
。事实上,即使将字节转换为十六进制字符串并取消验证也可能会更快,即使这项工作是原来的两倍多,如果您可以找到一种方法将这些主循环从Python移动到C。或者您可以合并调用
struct.unpack的结果,每次从
中解包8个字节,而不是逐个处理每个字节。但是这个版本应该易于理解和维护,并且不需要stdlib之外的任何东西。

您可能最好使用
pack
来实现这一点。实际上,我已经很惊讶Python-3.x能做到这一点,因为在Python-3.x中,
int
具有任意大小。当然,威廉。我们现在将查看文档。BT会处理签名的BtoTuriar到int转换,还是只有正整数?在发布之前,考虑复制并粘贴到谷歌搜索栏中。我使用的是Python 3.6.1 | Anaconda 4.4.0。当我在我的更高版本的Python中本地尝试此代码段时,它可以工作,但在2.7中却不能。对此,您可能最好使用
pack
。实际上,我已经很惊讶Python-3.x会这样做,因为在Python-3.x中,
int
具有任意大小。当然,Willem。我们现在将查看文档。BT会处理签名的BtoTuriar到int转换,还是只有正整数?在发布之前,考虑复制并粘贴到谷歌搜索栏中。我使用的是Python 3.6.1 | Anaconda 4.4.0。当我在更高版本的Python中本地尝试此代码段时,它可以工作,但在2.7中却不能。非常感谢……)工作顺利。也修改了问题标题@版主请随时更新它,如果它仍然似乎是误导。abarnert为具有类似要求的ppl编写的漂亮代码段。对于记录,转换为十六进制和解析要快得多
int(binascii.hexlify(mybytes),16)
非常快(我以前有理由重新发明这个,这个解决方案比任何其他选项都快几个数量级)。非常感谢:)工作顺利。也修改了问题标题@版主请随时更新它,如果它仍然似乎是误导。abarnert为具有类似要求的ppl编写的漂亮代码段。对于记录,转换为十六进制和解析要快得多
int(binascii.hexlify(mybytes),16)
真的很快(我以前有理由重新发明这个,这个解决方案比任何其他选项都快几个数量级)。