【问题标题】:Convert either a hex string or a bytearray into an integer将十六进制字符串或字节数组转换为整数
【发布时间】:2018-11-08 10:24:17
【问题描述】:

给定一个十六进制字符串或bytearray 的输入,我需要将其转换为整数。

当然,一种方法是检查类型,例如:

a = '0xb8c2659029395bdf'
b = bytearray([0xb8,0xc2,0x65,0x90,0x29,0x39,0x5b,0xdf])

def func(x):
    if type(x) == str:
        return int(x,16)
    else:
        return int('0x'+''.join(['{:02x}'.format(i) for i in x]),16)

print(func(a))
print(func(b))

但我正在寻找一种“更整洁”的方式。

我想到的一个想法是首先将输入转换为其中一种类型。

例如:

def func(x):
    return int(str(x),16)

或者:

def func(x):
    return int('0x'+''.join(['{:02x}'.format(i) for i in bytearray(x)]),16)

但对于第一个选项,我得到TypeError: string argument without an encoding

对于第二个选项,我得到ValueError: invalid literal for int() with base 16

知道如何解决这个问题,或者以不同的方式解决原来的问题吗?

【问题讨论】:

  • bytearray.fromhex("xxxxxx") ?

标签: python arrays string python-3.x


【解决方案1】:

“更整洁”并不总是更好。直接把字节数组转成整数,把字节数组转成字符串再把字符串转成整数是很浪费的。

例如。

def func(x):
    if isinstance(x, str):
        return int(x, base=16)
    else:
        assert isinstance(x, (bytearray, bytes))
        return int.from_bytes(x, byteorder='big')

assert func(bytearray(b'\xff\x00')) == func('0xff00') == 0xff00

【讨论】:

  • 我同意,但在我的情况下性能不是问题,所以我宁愿在编码方面更整洁。
  • 您希望实现什么目标?代码应该是简单的、文档化的、简洁的并按此顺序排列。性能是一个单独的考虑因素,优先于所有三个因素,但仅在性能至关重要时。我给出了我的答案,因为它比你的字节数组转换更简单,而不是因为它是高性能的。我不会以这种方式编写此函数的唯一原因是如果我在进行代码高尔夫挑战。
【解决方案2】:

您可以使用bytearray的hex方法将bytearray转换为可以解析的字符串:

def func(x):
    if hasattr(x, 'hex')
        x = x.hex()
    return int(x,16)

例如:

>>> func('0xffff')
65535
>>> func(bytearray([0xff, 0xff])) 
65535

【讨论】:

  • 好吧,你使用了if,那么这对我的方法有什么好处?
猜你喜欢
  • 2021-10-31
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 2017-06-17
相关资源
最近更新 更多