I converted my code from python 2 to python 3, everything is working well except for this part of the code:
from binascii import unhexlify
def swap_endian_words(hex_words):
'''Swaps the endianness of a hexidecimal string of words and converts to binary string.'''
message = unhexlify(hex_words)
if len(message) % 4 != 0: raise ValueError('Must be 4-byte word aligned')
return ''.join(([ message[4 * i: 4 * i 4][::-1] for i in range(0, len(message) // 4) ]))
print(swap_endian_words('aabbccdd'))
The console is giving me the output:
TypeError: sequence item 0: expected str instance, bytes found
I think that this is due to the fact that the program cannot iterate over bytes, which the variable message is formatted in. I tried to use .decode() on message, but it did not work.
CodePudding user response:
binascii.unhexlify
returns a bytes
object in Python 3, so the .join
should also use a bytes
string:
from binascii import unhexlify
def swap_endian_words(hex_words):
'''Swaps the endianness of a hexidecimal string of words and converts to binary string.'''
message = unhexlify(hex_words)
if len(message) % 4 != 0: raise ValueError('Must be 4-byte word aligned')
return b''.join(([ message[4 * i: 4 * i 4][::-1] for i in range(0, len(message) // 4) ]))
# ^ here
print(swap_endian_words('aabbccdd'))
Output:
b'\xdd\xcc\xbb\xaa'
Here's a faster version using array.array
:
import array
def swap_endian_words(hex_words):
'''Swaps the endianness of a hexadecimal string of words and converts to binary string.'''
# 'L' is unsigned 32-bit integer item type
arr = array.array('L', bytes.fromhex(hex_words))
arr.byteswap() # may want the final 32-bit integers
return arr.tobytes() # or dump back as bytes
print(swap_endian_words('00112233445566778899aabbccddeeff').hex(' '))
Output:
33 22 11 00 77 66 55 44 bb aa 99 88 ff ee dd cc