Why this construction:

data = bytes.fromhex(hex(int(binary_code, 2))[2:]) 

may give the following error:

ValueError: non-hexadecimal number found in fromhex () arg at position 39

    2 answers 2

    According to the documentation :

     classmethod bytes.fromhex(string) 

    This method of decoding the given string object. The string must contain two hexadecimal digits per byte, spaces are ignored.

    Those. This method breaks a hexadecimal number into bytes, biting off two digits for each byte. If your hex method returns a hexadecimal number with an odd number of digits, then the bytes.fromhex method bytes.fromhex throw an error.

    • How is it possible to avoid this? - Andrey
    • @Andrey, well, add a leading zero, if the length is odd - Kirill Malyshev
    • @Andrey, generally speaking, this method stackoverflow.com/a/30375198/7485582 should solve your problem - Cyril Malyshev

    Judging by the code, you want to turn the "01" string (bits in the form of ascii '0' / '1' characters written) into the corresponding bytes:

     >>> bits = "0101010001001111001000000100001001000101001000000100111101010010" >>> assert len(bits) % 8 == 0 >>> n = int(bits, 2) >>> n.to_bytes(len(bits) // 8, 'big') or '\0' b'TO BE OR' 

    Encoding text into arbitrary binary code and vice versa. Example: "A" <-> "01100011"


    You get an error if hex() returns an odd number of hexadecimal digits, which can be for example for characters with codes < 16 such as a new line:

     >>> bytes.fromhex(hex(int(bin(b'\n'[0])[2:], 2))) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: non-hexadecimal number found in fromhex() arg at position 1 non-hexadecimal number found in fromhex() arg at position 1 

    To avoid an error, up to the full byte, you can add bits to zero:

     >>> bin(b'\n'[0])[2:] '1010' >>> bits = _ >>> bits.zfill(8 * ((len(bits) + 7) // 8)) '00001010' >>> assert len(_) % 8 == 0