baseconv: tohex() -> tobytes(), fromhex() -> frombytes()
This commit is contained in:
parent
554703e541
commit
bec3dfeed2
2 changed files with 25 additions and 17 deletions
|
|
@ -349,7 +349,7 @@ class baseconv(object):
|
|||
'pad' argument to baseconv conversion methods must be either None, 'seed' or an integer.
|
||||
If None, output of minimum (but never zero) length will be produced.
|
||||
If 'seed', output length will be mapped from input length using data in seed_pad_lens.
|
||||
If an integer, it refers to the minimum allowable *string length* of the output.
|
||||
If an integer, the string, hex string or byte output will be padded to this length.
|
||||
"""
|
||||
if pad == None:
|
||||
return 0
|
||||
|
|
@ -364,6 +364,11 @@ class baseconv(object):
|
|||
@classmethod
|
||||
def tohex(cls,words_arg,wl_id,pad=None):
|
||||
"convert string or list data of base 'wl_id' to hex string"
|
||||
return cls.tobytes(words_arg,wl_id,pad//2 if type(pad)==int else pad).hex()
|
||||
|
||||
@classmethod
|
||||
def tobytes(cls,words_arg,wl_id,pad=None):
|
||||
"convert string or list data of base 'wl_id' to byte string"
|
||||
|
||||
words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
|
||||
|
||||
|
|
@ -376,9 +381,9 @@ class baseconv(object):
|
|||
if not len(words) in d:
|
||||
m = '{}: invalid length for seed-padded {} data in base conversion'
|
||||
raise BaseConversionError(m.format(len(words),wl_id))
|
||||
return d[len(words)] * 2
|
||||
return d[len(words)]
|
||||
|
||||
pad_val = max(cls.get_pad(pad,get_seed_pad),2)
|
||||
pad_val = max(cls.get_pad(pad,get_seed_pad),1)
|
||||
wl = cls.digits[wl_id]
|
||||
base = len(wl)
|
||||
|
||||
|
|
@ -386,38 +391,41 @@ class baseconv(object):
|
|||
m = ('{w!r}:','seed data')[pad=='seed'] + ' not in {i} (base{b}) format'
|
||||
raise BaseConversionError(m.format(w=words_arg,i=wl_id,b=base))
|
||||
|
||||
deconv = [wl.index(words[::-1][i])*(base**i) for i in range(len(words))]
|
||||
ret = ('{:0{w}x}'.format(sum(deconv),w=pad_val))
|
||||
return (('','0')[len(ret) % 2] + ret)
|
||||
ret = sum([wl.index(words[::-1][i])*(base**i) for i in range(len(words))])
|
||||
bl = ret.bit_length()
|
||||
return ret.to_bytes(max(pad_val,bl//8+bool(bl%8)),'big')
|
||||
|
||||
@classmethod
|
||||
def fromhex(cls,hexstr,wl_id,pad=None,tostr=False):
|
||||
"convert hex string to list or string data of base 'wl_id'"
|
||||
if wl_id in ('mmgen','tirosh','bip39'):
|
||||
assert tostr == False,"'tostr' must be False for '{}'".format(wl_id)
|
||||
|
||||
if not is_hex_str(hexstr):
|
||||
m = ('{h!r}:','seed data')[pad=='seed'] + ' not a hexadecimal string'
|
||||
raise HexadecimalStringError(m.format(h=hexstr))
|
||||
|
||||
if not hexstr:
|
||||
m = 'empty hex strings not allowed in base conversion'
|
||||
raise HexadecimalStringError(m)
|
||||
return cls.frombytes(bytes.fromhex(hexstr),wl_id,pad,tostr)
|
||||
|
||||
@classmethod
|
||||
def frombytes(cls,bytestr,wl_id,pad=None,tostr=False):
|
||||
"convert byte string to list or string data of base 'wl_id'"
|
||||
|
||||
if not bytestr:
|
||||
raise BaseConversionError('empty data not allowed in base conversion')
|
||||
|
||||
def get_seed_pad():
|
||||
assert wl_id in cls.seed_pad_lens,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seed_pad_lens[wl_id]
|
||||
slen = len(hexstr) // 2
|
||||
if not slen in d:
|
||||
if not len(bytestr) in d:
|
||||
m = '{}: invalid seed byte length for seed-padded base conversion'
|
||||
raise SeedLengthError(m.format(slen))
|
||||
return d[slen]
|
||||
raise SeedLengthError(m.format(len(bytestr)))
|
||||
return d[len(bytestr)]
|
||||
|
||||
pad = max(cls.get_pad(pad,get_seed_pad),1)
|
||||
wl = cls.digits[wl_id]
|
||||
base = len(wl)
|
||||
|
||||
num,ret = int(hexstr,16),[]
|
||||
num = int.from_bytes(bytestr,'big')
|
||||
ret = []
|
||||
while num:
|
||||
ret.append(num % base)
|
||||
num //= base
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ class unit_test(object):
|
|||
bad_data = (
|
||||
('hexstr', 'HexadecimalStringError', ': not a hexadecimal str', lambda:fh('x','b58')),
|
||||
('hexstr (seed)', 'HexadecimalStringError', 'seed data not a hexadec', lambda:fh('x','b58',pad='seed')),
|
||||
('hexstr (empty)', 'HexadecimalStringError', 'empty hex strings not', lambda:fh('','b58')),
|
||||
('hexstr (empty)', 'BaseConversionError', 'empty data not allowed', lambda:fh('','b58')),
|
||||
('b58 data', 'BaseConversionError', ': not in b58', lambda:th('IfFzZ','b58')),
|
||||
('b58 data (seed)', 'BaseConversionError', 'seed data not in b58', lambda:th(bad_b58,'b58',pad='seed')),
|
||||
('b58 len (seed)', 'BaseConversionError', 'invalid length for', lambda:th(bad_b58len,'b58',pad='seed')),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue