Advertisement
homer512

Int2BCD

Aug 19th, 2015
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.80 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3.  
  4. def make_nibbles(dec, high):
  5.     """Translates half of the dec digits into BCD nibble values
  6.  
  7.    Arguments:
  8.    dec -- a bytes object of decimal digits. Length has to be a multiple of 2
  9.    high -- defines if the high or low nibble per byte should be calculated
  10.  
  11.    Return value:
  12.    A bytes object representing the nibbles. The nibble that is not calculated
  13.    (per byte) is set to 0
  14.    """
  15.     assert(not (len(dec) & 1))
  16.     # build a translation table from decimal digits to BCD nibble values
  17.     translate_from = b'0123456789'
  18.     bitshift = 4 if high else 0
  19.     translate_to = bytes(num << bitshift for num in range(10))
  20.     # TODO: This table should only be calculated once and reused afterwards
  21.     table = bytes.maketrans(translate_from, translate_to)
  22.     byteshift = 0 if high else 1
  23.     bytes_ = dec[byteshift::2]
  24.     return bytes_.translate(table)
  25.  
  26.  
  27. def int2bcd(value):
  28.     """Encodes an integer into a bytes object of packed BCD values"""
  29.     dec = bytes(str(value), 'ascii')
  30.     padded_len = (len(dec) + 1) >> 1 << 1
  31.     padded_dec = dec.rjust(padded_len, b'0')
  32.     nibbles_low = make_nibbles(padded_dec, high=False)
  33.     nibbles_high = make_nibbles(padded_dec, high=True)
  34.     return bytes(high | low for high, low
  35.                  in zip(nibbles_high, nibbles_low))
  36.  
  37.  
  38. def bcd2int(bcd):
  39.     lowmask = (1 << 4) - 1
  40.     bytevals = [(byte_ & lowmask) + 10 * (byte_ >> 4) for byte_ in bcd]
  41.     return sum(byteval * 100**pow_ for pow_, byteval
  42.                in enumerate(reversed(bytevals)))
  43.    
  44.  
  45. def main():
  46.     value = int('42132801305034541=4101210013390'.replace("=", 'D'), 16)
  47.     bcd = int2bcd(value)
  48.     intval = bcd2int(bcd)
  49.     print("%d (%d) -> %s (%d) = %d" % (value, len(str(value)), bcd, len(bcd), intval))
  50.  
  51.  
  52. if __name__ == '__main__':
  53.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement