我有一个超过 256 位的大字符串,我需要将它的字节交换为 32 位。但字符串是十六进制的。当我查看 numpy 和数组模块时,我找不到关于如何进行覆盖的正确语法。有人可以帮我吗?
一个例子:(认为数据要长得多。我可以使用 pack 但我必须先将小端转换为十进制,然后再转换为大端,这似乎是一种浪费):
Input:12345678abcdeafa
Output:78563412faeacdab
我有一个超过 256 位的大字符串,我需要将它的字节交换为 32 位。但字符串是十六进制的。当我查看 numpy 和数组模块时,我找不到关于如何进行覆盖的正确语法。有人可以帮我吗?
一个例子:(认为数据要长得多。我可以使用 pack 但我必须先将小端转换为十进制,然后再转换为大端,这似乎是一种浪费):
Input:12345678abcdeafa
Output:78563412faeacdab
将字符串转换为字节,将 big-endian 32 位解包并打包 little-endian 32 位(反之亦然)并转换回字符串:
#!python3
import binascii
import struct
Input = b'12345678abcdeafa'
Output = b'78563412faeacdab'
def convert(s):
s = binascii.unhexlify(s)
a,b = struct.unpack('>LL',s)
s = struct.pack('<LL',a,b)
return binascii.hexlify(s)
print(convert(Input),Output)
输出:
b'78563412faeacdab' b'78563412faeacdab'
泛化为长度为 4 的倍数的任何字符串:
import binascii
import struct
Input = b'12345678abcdeafa'
Output = b'78563412faeacdab'
def convert(s):
if len(s) % 4 != 0:
raise ValueError('string length not multiple of 4')
s = binascii.unhexlify(s)
f = '{}L'.format(len(s)//4)
dw = struct.unpack('>'+f,s)
s = struct.pack('<'+f,*dw)
return binascii.hexlify(s)
print(convert(Input),Output)
如果它们真的是字符串,只需对它们进行字符串操作吗?
>>> input = "12345678abcdeafa"
>>> input[7::-1]+input[:7:-1]
'87654321afaedcba'
我的看法:
例子:
>>> source = '12345678abcdeafa87654321afaedcba'
>>> # small helper to slice the input in 8 digit chunks
>>> chunks = lambda iterable, sz: [iterable[i:i+sz]
for i in range(0, len(iterable), sz)]
>>> swap = lambda source, sz: ''.join([chunk[::-1]
for chunk in chunks(source, sz)])
原始问题中询问的输出:
>>> swap(source, 8)
'87654321afaedcba12345678abcdeafa'
在 icktoofay 编辑后很容易适应以匹配所需的输出:
>>> swap(swap(source, 8), 2)
'78563412faeacdab21436587badcaeaf'
一个正确的实现可能应该检查是否len(source) % 8 == 0
.