How to encode a number with the notation x and not 0x

Asked

Viewed 150 times

0

Problem

I’m performing a serial communication in which the checksum the message needs to be sent or verified upon receiving. This must be checked with a XOR logic, which returns an int number, given by the following function:

def XOR(hex):
    b = 0
    for a in hex:
        b = a ^ b
    return b

With the following example: x is the device response, as shown below:

Pacote de dados

And y are the data without STX ( X02), ETX ( x03) and checksum.

x = b'\x02\x02\x40\x0b\x00\x77\xc0\x00\x03\xfe'
y = x[1:-2]

The XOR() of y is 254 decimally or FE in hexadecimal, which shows that the function XOR() is correct.

Testing

By performing the same procedure when sending a message, you are generating an error, because the encoding returns 0xfe with i = hex(254).encode() or i = hex(XOR(y)).encode().

However, when entering the checksum manually with +b'\xfe' the message is sent correctly.

With the following test program:

a=b'0xfe'
b=b'\xfe'
print(int.from_bytes(a, byteorder='big'),int.from_bytes(b, byteorder='big'))

The following string 813196901 254 is printed, that is to say with b'0xfe' an error occurs when converting to Python.

Question

How I encode a number with the notation ' x' and not '0x'?

1 answer

1


The function hex gives you a string representation of the bytes passed to it, and this representation begins with 0x to indicate that it is a hexadecimal number. When you create a variable with b'', is creating an object bytes. Are different things.

Within a declaration of bytes in that format, the \x is an escape sequence indicating that the following are not the bytes equivalent to the characters "f" and "e", for example, but rather the number hexadecimally corresponding to "FE" (254). So the following are really different things:

a=b'0xfe'  # Declara os bytes \x30 \x78 \x66 \x65 (os quatro bytes que em ACII são 0 x f e)
b=b'\xfe'  # Declara um único byte \xFE (254)

>>> b'0xfe' == b'\x30\x78\x66\x65'
True

What you want to do with your number is convert it directly to an object bytes, without going through a string:

i = 254
i_bytes = i.to_bytes(1, 'big')

Upshot:

b = b'\xfe'

i = 254
i_bytes = i.to_bytes(1, 'big')
print(i_bytes)  # b'\xfe'

print(int.from_bytes(i_bytes, byteorder='big'), int.from_bytes(b, byteorder='big'))  # 254 254
print(type(b))        # <class 'bytes'>
print(type(i_bytes))  # <class 'bytes'>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.