我的目标是从用户那里获取一个 64 个字符长的十六进制数字(代表序列号)并转换为 c_type 32 字节的数字。 序列号定义如下:
_sn = c_ubyte * 32
我接受来自用户的SN字符串到 args.sn 变量中。这是我设法解决它的方法。我相信有一种更简单,更优雅的方法,感谢您的帮助。
SN_List= []
for i in range(0,len(args.sn),2):
myByte = args.sn[i: i+2]
num = int("0x" + myByte,16)
SN_List.append(num)
if(len(SN_List) != 32):
print("S/N is not valid, it should be 64 hex characters long")
return 1
_sn = (c_ubyte * 32)(*SN_List)
使用binascii
(Python 3)非常简单的方法:
import binascii
print(list(binascii.unhexlify(args.sn)))
例:
>>> list(binascii.unhexlify('09F911029D74E35BD84156C5635688C0'))
[9, 249, 17, 2, 157, 116, 227, 91, 216, 65, 86, 197, 99, 86, 136, 192]
在 Python 2 中,你会使用
print map(ord, args.sn.decode('hex'))
例:
>>> sn = '09F911029D74E35BD84156C5635688C0'
>>> print map(ord, sn.decode('hex'))
[9, 249, 17, 2, 157, 116, 227, 91, 216, 65, 86, 197, 99, 86, 136, 192]
扩展@nneonneo的评论(binascii.unhexlify
等同于binascii.a2b_hex
):
_sn = (c_ubyte * 32)(*binascii.unhexlify("ffaabb"))
示例(带十六进制ffaabb
):
>>> binascii.unhexlify("ffaabb")
b'xffxaaxbb'
>>> _sn = (c_ubyte * 32)(*binascii.unhexlify("ffaabb"))
>>> _sn
<__main__.c_ubyte_Array_32 object at 0x7fe14fee8bf8>
>>> for i in _sn:
... print(i)
...
255
170
187
0
0
<27 more zeros>
首先,您可以使用列表推导来消除大部分开销代码。其次,转换为 int 时,无需在字符串前面附加0x
,只要指定了第二个参数即可。第三,如果您需要验证字符串以确保它包含正确的位数,这应该是一个单独的步骤。或者,当出现问题时,您可以依靠引发的异常。
SN_List = [int(args.sn[i: i+2], 16) for i in range(0, 64, 2)]