Convert Hex string to Signed 16-bit integer big-endian Python

Question:

I have a hex string as follows:

"0d0d6e2800b900826bd000ba008a697800bc0094672000be009264c800bf0098627000c0009b601800c500c45dc000c600bf5b6800c700e2591000c800aa56b800c800ef546000c900b5520800ca00b84fb000ca00b74d5800cb00b84b0000cc00be48a800cc00ba465000cd00be43f800cd00bf41a000ce00c13f4800cf00c43cf000cf00c53a9800d000c3384000d000c935e800d100c6339000d100cb313800d200ca2ee000d300ca2c8800d300cc2a3000d300e227d800d400dd258000d400e0232800d600cd20d000d700cf1e7800d700d11c2000d700d519c800d800d4177000d800d6151800d800d412c000d800d6106800d800d70e1000d800d60bb800d800d3096000d800db070800d900d804b000d900db025800d800da000000d700da"

I need to convert this to Signed 16-bit integer big-endian and get the values that can be seen when converted through this online converter https://www.scadacore.com/tools/programming-calculators/online-hex-converter/

I am getting the correct values for some values but not others with the below code

        #data = hex string
        byte = bytearray.fromhex(data)

        for i in byte:
            print(i)

This gives me an output like below

13
13
110
40
0
185
0
130
107
208
0
186
0
138
105
120

But the larger values aren’t being converted properly. How do I do this in Python to mirror the results from the online converter?

Asked By: JackWeir

||

Answers:

You have converted the hex to bytes, but you never interpreted those bytes as a series of 16-bit ints. This can be done with the struct module:

import struct


hex_data = "0d0d6e2800b900826bd000ba008a697800bc0094672000be009264c800bf0098627000c0009b601800c500c45dc000c600bf5b6800c700e2591000c800aa56b800c800ef546000c900b5520800ca00b84fb000ca00b74d5800cb00b84b0000cc00be48a800cc00ba465000cd00be43f800cd00bf41a000ce00c13f4800cf00c43cf000cf00c53a9800d000c3384000d000c935e800d100c6339000d100cb313800d200ca2ee000d300ca2c8800d300cc2a3000d300e227d800d400dd258000d400e0232800d600cd20d000d700cf1e7800d700d11c2000d700d519c800d800d4177000d800d6151800d800d412c000d800d6106800d800d70e1000d800d60bb800d800d3096000d800db070800d900d804b000d900db025800d800da000000d700da"

bytes_data = bytes.fromhex(hex_data)

# ">" means big-endian, "h" means 16-bit int
num_ints = len(bytes_data) // 2
fmt = '>' + 'h' * num_ints  # alternatively: fmt = f'>{num_ints}h'
result = struct.unpack(fmt, bytes_data)

print(result)  # (3341, 28200, 185, 130, 27600, 186, ...)
Answered By: Aran-Fey

Try:

byte = bytearray.fromhex(data)
for i in range(0, len(byte), 2):
    value = (byte[i] << 8) + byte[i + 1]
    print(value)

Output:

3341
28200
185
130
27600
186
Answered By: Crapicus
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.