交换以字节为单位的十六进制数字对



我有一个二进制十六进制字符串,例如:b'x914x05x11x11x95hxf5'(在这种情况下,f是一个填充符(,预期结果是b'x914x05x11x11x95hxf5'91340511119568F519435011115986515

使用字符串和循环可能不是最好的解决方案(记录中有数百万条(,还有什么更好的方法呢?

编辑:忘记提及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的规则是什么,所以你必须自己添加这个逻辑。

最新更新