Skip to content Skip to sidebar Skip to footer

How To Byteswap 32bit Integers Inside A String In Python?

I have a large string more than 256 bits and and I need to byte swap it by 32 bits. But the string is in a hexadecimal base. When I looked at numpy and array modules I couldnt find

Solution 1:

Convert the string to bytes, unpack big-endian 32-bit and pack little-endian 32-bit (or vice versa) and convert back to a string:

#!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)

Output:

b'78563412faeacdab' b'78563412faeacdab'

Generalized for any string with length multiple of 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)

Solution 2:

If they really are strings, just do string operations on them?

>>> input = "12345678abcdeafa"
>>> input[7::-1]+input[:7:-1]
'87654321afaedcba'

Solution 3:

My take:

  1. slice the string in N digit chunks
  2. reverse each chunk
  3. concatenate everything

Example:

>>> 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)])

Output asked in the original question:

>>> swap(source, 8)
'87654321afaedcba12345678abcdeafa'

It is easy to adapt in order to match the required output after icktoofay edit:

>>> swap(swap(source, 8), 2)
'78563412faeacdab21436587badcaeaf'

A proper implementation probably should check if len(source) % 8 == 0.


Post a Comment for "How To Byteswap 32bit Integers Inside A String In Python?"