Python) Convert Big Endian to Little Endian

Viewed 525

I have a file (.vcon) that contains hexadecimal strings (around 2,000 bytes) stored in big endian and want to convert this file to little endian hexadecimal string .vcon file based on the rule set.

Inside a list, there are four possible values : 8, 16, 32, 64 If a number in a list is 8, then no switiching (from big to little endian) is necessary since the data is one byte. Other than 8, the data must be switched from big to little endian.

I have trouble coming up with a way to go about this.

For example, if my data in the .vcon file (big endian) is as follows

F324658951425AF3EB0011

and the numbers in the list are as follows

[16, 8, 8, 32, 8, 16] 

then the resulting data we create should be as follows (to little endian)

24F36589F35A4251EB1100

How should I iterate through the numbers in a list while also accessing each byte in a hexadecimal string file (that is in big endian format) and create a new hexadecimal string file in little endian format?

4 Answers

I would probably loop thorugh your rule list (your [16, 8, 8, 32, 8, 16]). For each element in rule, take rule[i]/8 touples from .vcon and add these touples in reverse order to your result.

Like so:

rule = [16, 8, 8, 32, 8, 16] 
bigE = 'F324658951425AF3EB0011'
littleE = ''

for x in rule:
    n = x//4
    word, bigE = bigE[:n], bigE[n:]
    for i in range(x//8):        
        word, byte = word[:-2], word[-2:]
        littleE += byte
        
print(littleE)

Here's a simplistic but effective approach:

hs = 'F324658951425AF3EB0011'
m = [16, 8, 8, 32, 8, 16]
idx = 0
result = ''
for w in m:
    match w:
        case 8:
            result += hs[idx:idx+2]
        case 16:
            result += hs[idx+2:idx+4] + hs[idx:idx+2]
        case 32:
            result += hs[idx+6:idx+8] + hs[idx+4:idx+6] + hs[idx+2:idx+4] + hs[idx:idx+2]
    idx += w // 4
print(result)

Output:

24F36589F35A4251EB1100

In broad strokes,

>>> data = "F324658951425AF3EB0011"
>>> bits = [16, 8, 8, 32, 8, 16]

I would first just get the individual byte-sized (i.e. two hex characters) pieces:

>>> bs = [data[i:i+2] for i in range(0, len(data), 2)] # get individual bytes
>>> bs
['F3', '24', '65', '89', '51', '42', '5A', 'F3', 'EB', '00', '11']

Then, I would use an iterator to take a number of bytes based on the value in the bits list (a byte per 8 bits), then add this chunk of strings to a list in reversed order. Then join at the end:

>>> iterator = iter(bs)
>>> result = []
>>> for n in bits:
...     chunk = [next(iterator) for _ in range(n//8)]
...     result.extend(reversed(chunk))
...
>>> print("".join(result))
24F36589F35A4251EB1100

Using a bytearray (Try it online!):

data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]

b = bytearray.fromhex(data)
i = 0
for n in bits:
    n //= 8
    b[i:i+n] = reversed(b[i:i+n])
    i += n
print(b.hex().upper())

Or with memoryview (Try it online!):

data = "F324658951425AF3EB0011"
bits = [16, 8, 8, 32, 8, 16]

b = bytearray.fromhex(data)
m = memoryview(b)
for n in bits:
    n //= 8
    m[:n] = m[n-1::-1]
    m = m[n:]
print(b.hex().upper())
Related