I need to convert an Int left padded 6 bytes (amount) to a BCD in Python.
int = 145
expect = "\x00\x00\x00\x00\x01\x45"
The closest I come is with this code (but it needs to loop in byte pair):
def TO_BCD(value):
return chr((((value / 10) << 4) & 0xF0) + ((value % 10) & 0x0F))
int = 145
TO_BCD(int) # => "\x00\x00\x00\x00\x01\x45" (expected)
This seems fairly simple, and gets the answer you were looking for. Just isolate each pair of digits and convert to ASCII.
If I were doing this in high volume then I'd probably build a table (perhaps in numpy) of all the possible 100 values per byte and index it with each pair of digits in the input.
m = 145
print(''.join(f"\\x{m // 10**i % 10}{m // 10**(i-1) % 10}" for i in range(11, -1, -2)))
Output, although it's just a string, not any internal BCD representation
\x00\x00\x00\x00\x01\x45
Along the same lines, you can pack the BCD into a byte string. When printed, Python will interpret BCD 45
as a capital E
import struct
m = 145
packed = struct.pack('6B', *[(m // 10**i % 10 << 4) + (m // 10**(i-1) % 10) for i in range(11, -1, -2)])
print(packed)
print(''.join(f"\\{p:02x}" for p in packed))
Output
b'\x00\x00\x00\x00\x01E'
\00\00\00\00\01\45