hexathon

Common and uncommon hex string operations for python3
git clone git://git.defalsify.org/python-hexathon.git
Log | Files | Refs | LICENSE

parse.py (3287B)


      1 import re
      2 
      3 
      4 __re_valid = '^[0-9a-fA-F]+$'
      5 def valid(hx, allow_compact=False):
      6     l = len(hx)
      7     if l == 0:
      8         raise ValueError('invalid hex (invalid length {})'.format(l))
      9     if not allow_compact and l % 2 != 0:
     10         raise ValueError('invalid hex (invalid length {}, no compact allowed)'.format(l))
     11     if not re.match(__re_valid, hx):
     12         raise ValueError('invalid hex (non-hex character)')
     13     return hx
     14 
     15 
     16 def even(hx, allow_empty=False, allow_compact=False):
     17     if len(hx) % 2 != 0:
     18         hx = '0' + hx
     19     if allow_empty and len(hx) == 0:
     20         return ''
     21     return valid(hx, allow_compact=allow_compact)
     22 
     23 
     24 def uniform(hx, allow_empty=False, compact_value=False):
     25     if compact_value:
     26         return hx.lower()
     27     return even(hx, allow_empty=allow_empty).lower()
     28 
     29 
     30 def strip_0x(hx, allow_empty=False, compact_value=False, pad=True):
     31     if len(hx) == 0 and not allow_empty:
     32         raise ValueError('invalid hex')
     33     elif len(hx) > 1:
     34         if hx[:2] == '0x':
     35             hx = hx[2:]
     36     if len(hx) > 0:
     37         hx = valid(hx, allow_compact=True)
     38 
     39     if compact_value:
     40         v = compact(hx, allow_empty=allow_empty)
     41     elif pad:
     42         v = even(hx, allow_empty=allow_empty, allow_compact=True)
     43     else:
     44         v = hx
     45     return v
     46 
     47 
     48 def add_0x(hx, allow_empty=False, compact_value=False, pad=True):
     49     if len(hx) == 0 and not allow_empty:
     50         raise ValueError('invalid hex')
     51     if hx[:2] == '0x':
     52         hx = hx[2:]
     53     v = ''
     54     if compact_value:
     55         v = compact(hx, allow_empty=allow_empty)
     56     elif pad:
     57         v = even(hx, allow_empty=allow_empty, allow_compact=True)
     58     else:
     59         v = hx
     60     return '0x' + v
     61 
     62 
     63 def compact(hx, allow_empty=False):
     64     if len(hx) == 0:
     65         if not allow_empty:
     66             raise ValueError('invalid hex (empty)')
     67     else:
     68         hx = valid(hx, allow_compact=True)
     69     i = 0
     70     for i in range(len(hx)):
     71         if hx[i] != '0':
     72             break
     73     return hx[i:]
     74 
     75 
     76 def unpad(hx):
     77     return even(compact(hx))
     78 
     79 
     80 def pad(hx, byte_length=0, allow_compact=False):
     81     hx = valid(hx, allow_compact=allow_compact)
     82     if byte_length == 0:
     83        hx = even(hx, allow_compact=allow_compact)
     84     else:
     85         hx = hx.rjust(byte_length * 2, '0')
     86     return hx
     87 
     88 
     89 def int_to_minbytes(v, byteorder='big'):
     90 #    c = 0x100
     91 #    i = 1
     92 #    while c <= v:
     93 #        i += 1
     94 #        c = c << 8
     95     l = ((v.bit_length() - 1) >> 3) + 1
     96     return v.to_bytes(l, byteorder=byteorder)
     97 
     98 
     99 def int_to_minhex(v):
    100     return int_to_minbytes(v).hex()
    101 
    102 
    103 def to_int(v, need_prefix=False):
    104     if len(v) == 0:
    105         raise ValueError('empty value')
    106     if need_prefix:
    107         if len(v) < 2:
    108             raise ValueError('value too short')
    109         if v[:2] != '0x':
    110             raise ValueError('missing prefix')
    111 
    112     v = strip_0x(v)
    113     return int(v, 16)
    114 
    115 
    116 def same(x, y, allow_empty=False, compact_value=False, pad=True):
    117     no_uniform_compact = compact_value or not pad
    118 
    119     vl = strip_0x(x, allow_empty=allow_empty, compact_value=compact_value, pad=pad)
    120     vl = uniform(vl, allow_empty=allow_empty, compact_value=no_uniform_compact)
    121 
    122     vr = strip_0x(y, allow_empty=allow_empty, compact_value=compact_value, pad=pad)
    123     vr = uniform(vr, allow_empty=allow_empty, compact_value=no_uniform_compact)
    124 
    125     return vl == vr