我有一个二进制十六进制字符串,例如:b'x914x05x11x11x95hxf5'
(在这种情况下,f
是一个填充符(,预期结果是b'x914x05x11x11x95hxf5'
→91340511119568F5
→19435011115986515
。
使用字符串和循环可能不是最好的解决方案(记录中有数百万条(,还有什么更好的方法呢?
编辑:忘记提及f只是从服务器(网络交换机(添加的填充符,为交换机提供偶数(如mkrieger所述(
您所拥有的是一个bytes
对象。当迭代它时,你会得到整数值:
>>> s = b'x914x05x11x11x95hxf5'
>>> list(s) # equivalent to [b for b in s]
[145, 52, 5, 17, 17, 149, 104, 245]
为了交换这两个";"半字节";如果字节由整数值表示,则可以使用逐位运算。要选择较高值的半字节,请使用逐位和的位掩码0xF0
(&
(,要选择较低值的半比特,请使用0x0F
。然后在各自的方向上将它们移位4位,并将它们与逐位或(|
(:再次组合
def swap_nibbles(b: int) -> int:
return ((b & 0xF0) >> 4) | ((b & 0x0F) << 4)
现在,您可以对s
中的所有字节执行此操作,以获得具有交换半字节的字节值列表:
>>> swapped_nibbles = [swap_nibbles(b) for b in s]
# [25, 67, 80, 17, 17, 89, 134, 95]
现在你只需要把这些数字重新组合成你想要的结果。我不完全确定你到底想要什么,所以这里有一些选择:
要获得另一个
bytes
对象:只需使用bytes
构造函数。>>> bytes(swapped_nibbles) b'x19CPx11x11Yx86_'
要获取整数:请使用具有big-endian字节顺序的
int.from_bytes
构造函数。>>> int.from_bytes(swapped_nibbles, byteorder='big') 1820386708623558239 # == 0x194350111159865F
要获得十六进制字符串:对上面的整数使用
hex
,或者从单个字节构建:>>> ''.join(f'{b:02X}' for b in swapped_nibbles) '194350111159865F'
我不清楚从结果中排除最后一个F
的规则是什么,所以你必须自己添加这个逻辑。