Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- def make_nibbles(dec, high):
- """Translates half of the dec digits into BCD nibble values
- Arguments:
- dec -- a bytes object of decimal digits. Length has to be a multiple of 2
- high -- defines if the high or low nibble per byte should be calculated
- Return value:
- A bytes object representing the nibbles. The nibble that is not calculated
- (per byte) is set to 0
- """
- assert(not (len(dec) & 1))
- # build a translation table from decimal digits to BCD nibble values
- translate_from = b'0123456789'
- bitshift = 4 if high else 0
- translate_to = bytes(num << bitshift for num in range(10))
- # TODO: This table should only be calculated once and reused afterwards
- table = bytes.maketrans(translate_from, translate_to)
- byteshift = 0 if high else 1
- bytes_ = dec[byteshift::2]
- return bytes_.translate(table)
- def int2bcd(value):
- """Encodes an integer into a bytes object of packed BCD values"""
- dec = bytes(str(value), 'ascii')
- padded_len = (len(dec) + 1) >> 1 << 1
- padded_dec = dec.rjust(padded_len, b'0')
- nibbles_low = make_nibbles(padded_dec, high=False)
- nibbles_high = make_nibbles(padded_dec, high=True)
- return bytes(high | low for high, low
- in zip(nibbles_high, nibbles_low))
- def bcd2int(bcd):
- lowmask = (1 << 4) - 1
- bytevals = [(byte_ & lowmask) + 10 * (byte_ >> 4) for byte_ in bcd]
- return sum(byteval * 100**pow_ for pow_, byteval
- in enumerate(reversed(bytevals)))
- def main():
- value = int('42132801305034541=4101210013390'.replace("=", 'D'), 16)
- bcd = int2bcd(value)
- intval = bcd2int(bcd)
- print("%d (%d) -> %s (%d) = %d" % (value, len(str(value)), bcd, len(bcd), intval))
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement