Search on blog:

Python: How to use module struct-to-convert-(un)signed-byte-to-integer-value

In languages like C/C++ when you use signed byte then value \xff means -1 (and byte can have values -128...127) and when you use unsigned byte then value \xff means 255 (and byte can have values 0...255)

Similar with 16-bits - value \xff\xff means -1 when you use signed variable and 65535 when you use unsigned variable.

In Python all bytes as unsigned and it means only positive values 0-255. And you can't use it integer value. You have to convert byte to int You can use standard module struct and function unpack(format, buffer) to convert byte(s) to integer. With different format you can convert it as signed or unsigned value.

    import struct

    # b - signed char (8-bits / 1-byte)
    results = struct.unpack('b', b'\xff')
    print(results[0])  # -1  

    # B - unsigned char (8-bits / 1-byte)
    results = struct.unpack('B', b'\xff')
    print(results[0])  # 255

    # h - signed short (16-bits / 2-bytes)    
    results = struct.unpack('h', b'\xff\xff')
    print(results[0])  # -1

    # H - unsigned short (16-bits / 2-bytes)    
    results = struct.unpack('H', b'\xff\xff')
    print(results[0])  # 65535

I use [0] because it can unpack many values at the same time and it always returns tuple with result - even if there is only one value.

Example with four signed bytes

    # b - signed char (8-bits / 1-byte) 
    results = struct.unpack('bbbb', b'\xff\xfe\xfd\xfc')
    print(results)  # (-1, -2, -3, -4)  

Module struct has also function pack(format, buffer) to convert integer to byte(s). And again with different format you can convert it as signed or unsigned value.

Both functions can be useful to use in file or socket to send information with fixed size - ie. to send information how many data receiver has to read from socket or how many data is in file. Using format I (unsigned int) you can keep every value 0..4294967295 in 4 bytes (fixed size) and you have to always receive 4 bytes from file or socket to get size of data.

    # I - unsigned int (4-bytes)
    results = struct.unpack('I', b'\xff\xfe\xfd\xfc')
    print(results[0])  # 4294967295

More formats in documentation: struct

BTW: Using decode you can't convert unsigned to signed value. You can't even convert byte value to the same integer value. It will always convert to char with this code.

If you like it
Buy a Coffee