base conversion: rework pad API, forbid empty input and output
This commit is contained in:
parent
8e232f24bb
commit
186f223646
6 changed files with 144 additions and 66 deletions
|
|
@ -38,12 +38,16 @@ class UnrecognizedTokenSymbol(Exception): mmcode = 2
|
|||
class TokenNotInBlockchain(Exception): mmcode = 2
|
||||
class TokenNotInWallet(Exception): mmcode = 2
|
||||
class BadTwComment(Exception): mmcode = 2
|
||||
class BaseConversionError(Exception): mmcode = 2
|
||||
class BaseConversionPadError(Exception): mmcode = 2
|
||||
|
||||
# 3: yellow hl, 'MMGen Error' + exception + message
|
||||
class RPCFailure(Exception): mmcode = 3
|
||||
class BadTxSizeEstimate(Exception): mmcode = 3
|
||||
class MaxInputSizeExceeded(Exception): mmcode = 3
|
||||
class WalletFileError(Exception): mmcode = 3
|
||||
class HexadecimalStringError(Exception): mmcode = 3
|
||||
class SeedLengthError(Exception): mmcode = 3
|
||||
|
||||
# 4: red hl, 'MMGen Fatal Error' + exception + message
|
||||
class BadMMGenTxID(Exception): mmcode = 4
|
||||
|
|
|
|||
|
|
@ -972,7 +972,7 @@ class MMGenSeedFile(SeedSourceUnenc):
|
|||
ext = 'mmseed'
|
||||
|
||||
def _format(self):
|
||||
b58seed = baseconv.b58encode(self.seed.data,pad=True)
|
||||
b58seed = baseconv.b58encode(self.seed.data,pad='seed')
|
||||
self.ssdata.chksum = make_chksum_6(b58seed)
|
||||
self.ssdata.b58seed = b58seed
|
||||
self.fmt_data = '{} {}\n'.format(self.ssdata.chksum,split_into_cols(4,b58seed))
|
||||
|
|
@ -1000,7 +1000,7 @@ class MMGenSeedFile(SeedSourceUnenc):
|
|||
if not compare_chksums(a,'file',make_chksum_6(b),'computed',verbose=True):
|
||||
return False
|
||||
|
||||
ret = baseconv.b58decode(b,pad=True)
|
||||
ret = baseconv.b58decode(b,pad='seed')
|
||||
|
||||
if ret == False:
|
||||
msg('Invalid base-58 encoded seed: {}'.format(val))
|
||||
|
|
@ -1146,8 +1146,8 @@ class Wallet (SeedSourceEnc):
|
|||
def _format(self):
|
||||
d = self.ssdata
|
||||
s = self.seed
|
||||
slt_fmt = baseconv.b58encode(d.salt,pad=True)
|
||||
es_fmt = baseconv.b58encode(d.enc_seed,pad=True)
|
||||
slt_fmt = baseconv.b58encode(d.salt,pad='seed')
|
||||
es_fmt = baseconv.b58encode(d.enc_seed,pad='seed')
|
||||
lines = (
|
||||
d.label,
|
||||
'{} {} {} {} {}'.format(s.sid.lower(), d.key_id.lower(),
|
||||
|
|
@ -1205,7 +1205,7 @@ class Wallet (SeedSourceEnc):
|
|||
msg("Hash parameters '{}' don't match hash preset '{}'".format(' '.join(hash_params),d.hash_preset))
|
||||
return False
|
||||
|
||||
lmin,foo,lmax = [v for k,v in baseconv.b58pad_lens] # 22,33,44
|
||||
lmin,foo,lmax = sorted(baseconv.seed_pad_lens_rev['b58']) # 22,33,44
|
||||
for i,key in (4,'salt'),(5,'enc_seed'):
|
||||
l = lines[i].split(' ')
|
||||
chk = l.pop(0)
|
||||
|
|
@ -1219,7 +1219,7 @@ class Wallet (SeedSourceEnc):
|
|||
make_chksum_6(b58_val),'computed checksum',verbose=True):
|
||||
return False
|
||||
|
||||
val = baseconv.b58decode(b58_val,pad=True)
|
||||
val = baseconv.b58decode(b58_val,pad='seed')
|
||||
if val == False:
|
||||
msg('Invalid base 58 number: {}'.format(b58_val))
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ class MMGenToolCmdUtil(MMGenToolCmdBase):
|
|||
return make_chksum_8(
|
||||
get_data_from_file(infile,dash=True,quiet=True,binary=True))
|
||||
|
||||
def randb58(self,nbytes=32,pad=True):
|
||||
def randb58(self,nbytes=32,pad=0):
|
||||
"generate random data (default: 32 bytes) and convert it to base 58"
|
||||
return baseconv.b58encode(get_random(nbytes),pad=pad)
|
||||
|
||||
|
|
|
|||
106
mmgen/util.py
106
mmgen/util.py
|
|
@ -295,8 +295,12 @@ class baseconv(object):
|
|||
'tirosh': '48f05e1f', # tirosh truncated to mn_base (1626)
|
||||
# 'tirosh1633': '1a5faeff'
|
||||
}
|
||||
b58pad_lens = [(16,22), (24,33), (32,44)]
|
||||
b58pad_lens_rev = [(v,k) for k,v in b58pad_lens]
|
||||
seed_pad_lens = {
|
||||
'b58': { 16:22, 24:33, 32:44 },
|
||||
}
|
||||
seed_pad_lens_rev = {
|
||||
'b58': { 22:16, 33:24, 44:32 },
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def init_mn(cls,mn_id):
|
||||
|
|
@ -310,31 +314,6 @@ class baseconv(object):
|
|||
else: # bip39
|
||||
cls.digits[mn_id] = cls.words
|
||||
|
||||
@classmethod
|
||||
def b58encode(cls,s,pad=None):
|
||||
pad = cls._get_pad(s,pad,'b58encode',cls.b58pad_lens,(bytes,))
|
||||
return cls.fromhex(s.hex(),'b58',pad=pad,tostr=True)
|
||||
|
||||
@classmethod
|
||||
def b58decode(cls,s,pad=None):
|
||||
pad = cls._get_pad(s,pad,'b58decode',cls.b58pad_lens_rev,(bytes,str))
|
||||
return bytes.fromhex(cls.tohex(s,'b58',pad=pad*2 if pad else None))
|
||||
|
||||
@staticmethod
|
||||
def _get_pad(s,pad,op_desc,pad_map,ok_types):
|
||||
if not isinstance(s,ok_types):
|
||||
m = "{}() input must be one of {}, not '{}'"
|
||||
raise ValueError(m.format(op_desc,repr([t.__name__ for t in ok_types]),type(s).__name__))
|
||||
if pad:
|
||||
assert type(pad) == bool,"'pad' must be boolean type"
|
||||
d = dict(pad_map)
|
||||
if not len(s) in d:
|
||||
m = 'Invalid data length for {}(pad=True) (must be one of {})'
|
||||
raise ValueError(m.format(op_desc,repr([e[0] for e in pad_map])))
|
||||
return d[len(s)]
|
||||
else:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_wordlist(cls,wl_id):
|
||||
cls.init_mn(wl_id)
|
||||
|
|
@ -364,38 +343,97 @@ class baseconv(object):
|
|||
|
||||
qmsg('List is sorted') if tuple(sorted(wl)) == wl else die(3,'ERROR: List is not sorted!')
|
||||
|
||||
@classmethod
|
||||
def get_pad(cls,pad,seed_pad_func):
|
||||
"""
|
||||
'pad' argument to applicable baseconv 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 seed_pad_lens.
|
||||
If an integer, it refers to the minimum allowable *string length* of the output.
|
||||
"""
|
||||
if pad == None:
|
||||
return 0
|
||||
elif isinstance(pad,int) and type(pad) != bool:
|
||||
return pad
|
||||
elif pad == 'seed':
|
||||
return seed_pad_func()
|
||||
else:
|
||||
m = "{!r}: illegal value for 'pad' (must be None,'seed' or int)"
|
||||
raise BaseConversionPadError(m.format(pad))
|
||||
|
||||
@classmethod
|
||||
def tohex(cls,words_arg,wl_id,pad=None):
|
||||
"convert string or list data of base specified by 'wl_id' to hex string"
|
||||
|
||||
words = words_arg if isinstance(words_arg,(list,tuple)) else tuple(words_arg.strip())
|
||||
|
||||
if len(words) == 0:
|
||||
raise BaseConversionError('empty {} data'.format(wl_id))
|
||||
|
||||
def get_seed_pad():
|
||||
assert wl_id in cls.seed_pad_lens_rev,'seed padding not supported for base {!r}'.format(wl_id)
|
||||
d = cls.seed_pad_lens_rev[wl_id]
|
||||
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
|
||||
|
||||
pad = max(cls.get_pad(pad,get_seed_pad),2)
|
||||
wl = cls.digits[wl_id]
|
||||
base = len(wl)
|
||||
|
||||
if not set(words) <= set(wl):
|
||||
die(2,'{} is not in {} (base{}) format'.format(repr(words_arg),wl_id,base))
|
||||
m = '{!r}: not in {} (base{}) format'
|
||||
raise BaseConversionError(m.format(words_arg,wl_id,base))
|
||||
|
||||
deconv = [wl.index(words[::-1][i])*(base**i) for i in range(len(words))]
|
||||
ret = ('{:0{w}x}'.format(sum(deconv),w=pad or 0))
|
||||
ret = ('{:0{w}x}'.format(sum(deconv),w=pad))
|
||||
return (('','0')[len(ret) % 2] + ret)
|
||||
|
||||
@classmethod
|
||||
def fromhex(cls,hexnum,wl_id,pad=None,tostr=False):
|
||||
def fromhex(cls,hexstr,wl_id,pad=None,tostr=False):
|
||||
"convert hex string to list or string data of base specified by '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(hexnum):
|
||||
die(2,"{!r}: not a hexadecimal number".format(hexnum))
|
||||
if not is_hex_str(hexstr):
|
||||
m = '{!r}: not a hexadecimal string'
|
||||
raise HexadecimalStringError(m.format(hexstr))
|
||||
|
||||
if not hexstr:
|
||||
m = 'empty hex strings not allowed in base conversion'
|
||||
raise HexadecimalStringError(m)
|
||||
|
||||
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:
|
||||
m = '{}: invalid seed byte length for seed-padded base conversion'
|
||||
raise SeedLengthError(m.format(slen))
|
||||
return d[slen]
|
||||
|
||||
pad = max(cls.get_pad(pad,get_seed_pad),1)
|
||||
wl = cls.digits[wl_id]
|
||||
base = len(wl)
|
||||
num,ret = int(hexnum,16),[]
|
||||
|
||||
num,ret = int(hexstr,16),[]
|
||||
while num:
|
||||
ret.append(num % base)
|
||||
num //= base
|
||||
o = [wl[n] for n in [0] * ((pad or 0)-len(ret)) + ret[::-1]]
|
||||
o = [wl[n] for n in [0] * (pad-len(ret)) + ret[::-1]]
|
||||
return ''.join(o) if tostr else o
|
||||
|
||||
@classmethod
|
||||
def b58decode(cls,s,pad=None):
|
||||
'convert base58 string to bytes'
|
||||
return bytes.fromhex(cls.tohex(s,'b58',pad=pad))
|
||||
|
||||
@classmethod
|
||||
def b58encode(cls,s,pad=None):
|
||||
'convert bytes to base58 string'
|
||||
return cls.fromhex(s.hex(),'b58',pad=pad,tostr=True)
|
||||
|
||||
def match_ext(addr,ext):
|
||||
return addr.split('.')[-1] == ext
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ tests = {
|
|||
( ['deadbeef'], 'DPK3PXP' ),
|
||||
( ['deadbeefdeadbeef'], 'N5LN657PK3PXP' ),
|
||||
( ['ffffffffffffffff'], 'P777777777777' ),
|
||||
( ['0000000000000000'], '' ),
|
||||
( ['0000000000000000'], 'A' ),
|
||||
( ['0000000000000000','pad=10'], 'AAAAAAAAAA' ),
|
||||
( ['ff','pad=10'], 'AAAAAAAAH7' ),
|
||||
],
|
||||
|
|
@ -171,7 +171,7 @@ tests = {
|
|||
( ['DPK3PXP'], 'deadbeef' ),
|
||||
( ['N5LN657PK3PXP'], 'deadbeefdeadbeef' ),
|
||||
( ['P777777777777'], 'ffffffffffffffff' ),
|
||||
( ['','pad=16'], '0000000000000000' ),
|
||||
( ['A','pad=16'], '0000000000000000' ),
|
||||
( ['AAAAAAAAAA','pad=16'], '0000000000000000' ),
|
||||
( ['AAAAAAAAH7','pad=2'], 'ff' ),
|
||||
],
|
||||
|
|
@ -180,7 +180,7 @@ tests = {
|
|||
( ['deadbeefdeadbeef'], '5CizhNNRPYpBjrbYX' ),
|
||||
( ['ffffffffffffffff'], '5qCHTcgbQwprzjWrb' ),
|
||||
( ['0000000000000000'], '111111114FCKVB' ),
|
||||
( [''], '3QJmnh' ),
|
||||
( ['00'], '1Wh4bh' ),
|
||||
( ['000000000000000000000000000000000000000000'], '1111111111111111111114oLvT2' ),
|
||||
],
|
||||
'b58chktohex': [
|
||||
|
|
@ -195,7 +195,7 @@ tests = {
|
|||
( [b'\xde\xad\xbe\xef'], '6h8cQN' ),
|
||||
( [b'\xde\xad\xbe\xef\xde\xad\xbe\xef'], 'eFGDJURJykA' ),
|
||||
( [b'\xff\xff\xff\xff\xff\xff\xff\xff'], 'jpXCZedGfVQ' ),
|
||||
( [b'\x00\x00\x00\x00\x00\x00\x00\x00'], '' ),
|
||||
( [b'\x00\x00\x00\x00\x00\x00\x00\x00'], '1' ),
|
||||
( [b'\x00\x00\x00\x00\x00\x00\x00\x00','pad=10'], '1111111111' ),
|
||||
( [b'\xff','pad=10'], '111111115Q' ),
|
||||
],
|
||||
|
|
@ -203,7 +203,7 @@ tests = {
|
|||
( ['6h8cQN'], b'\xde\xad\xbe\xef' ),
|
||||
( ['eFGDJURJykA'], b'\xde\xad\xbe\xef\xde\xad\xbe\xef' ),
|
||||
( ['jpXCZedGfVQ'], b'\xff\xff\xff\xff\xff\xff\xff\xff' ),
|
||||
( ['','pad=16'], b'\x00\x00\x00\x00\x00\x00\x00\x00' ),
|
||||
( ['1','pad=16'], b'\x00\x00\x00\x00\x00\x00\x00\x00' ),
|
||||
( ['1111111111','pad=16'], b'\x00\x00\x00\x00\x00\x00\x00\x00' ),
|
||||
( ['111111115Q','pad=2'], b'\xff' ),
|
||||
],
|
||||
|
|
@ -211,7 +211,7 @@ tests = {
|
|||
( ['deadbeef'], '6h8cQN' ),
|
||||
( ['deadbeefdeadbeef'], 'eFGDJURJykA' ),
|
||||
( ['ffffffffffffffff'], 'jpXCZedGfVQ' ),
|
||||
( ['0000000000000000'], '' ),
|
||||
( ['0000000000000000'], '1' ),
|
||||
( ['0000000000000000','pad=10'], '1111111111' ),
|
||||
( ['ff','pad=10'], '111111115Q' ),
|
||||
],
|
||||
|
|
@ -219,7 +219,7 @@ tests = {
|
|||
( ['6h8cQN'], 'deadbeef' ),
|
||||
( ['eFGDJURJykA'], 'deadbeefdeadbeef' ),
|
||||
( ['jpXCZedGfVQ'], 'ffffffffffffffff' ),
|
||||
( ['','pad=16'], '0000000000000000' ),
|
||||
( ['1','pad=16'], '0000000000000000' ),
|
||||
( ['1111111111','pad=16'], '0000000000000000' ),
|
||||
( ['111111115Q','pad=2'], 'ff' ),
|
||||
],
|
||||
|
|
@ -274,9 +274,9 @@ tests = {
|
|||
( ['nbytes=6'], {'boolfunc':is_hex_str,'len':12}, ['-r0'] ),
|
||||
],
|
||||
'randb58': [
|
||||
( [], {'boolfunc':is_b58_str,'len':44}, ['-r0'] ),
|
||||
( [], {'boolfunc':is_b58_str}, ['-r0'] ),
|
||||
( ['nbytes=16'], {'boolfunc':is_b58_str,'len':22}, ['-r0'] ),
|
||||
( ['nbytes=12','pad=false'], is_b58_str, ['-r0'] ),
|
||||
( ['nbytes=12','pad=0'], is_b58_str, ['-r0'] ),
|
||||
],
|
||||
},
|
||||
'Wallet': {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class unit_test(object):
|
|||
|
||||
vectors = {
|
||||
'b58': (
|
||||
(('00',None),''),
|
||||
(('00',None),'1'),
|
||||
(('00',1),'1'),
|
||||
(('00',2),'11'),
|
||||
(('01',None),'2'),
|
||||
|
|
@ -21,14 +21,20 @@ class unit_test(object):
|
|||
(('0f',2),'1G'),
|
||||
(('deadbeef',None),'6h8cQN'),
|
||||
(('deadbeef',20),'111111111111116h8cQN'),
|
||||
(('00000000',None),''),
|
||||
(('00000000',None),'1'),
|
||||
(('00000000',20),'11111111111111111111'),
|
||||
(('ffffffff',None),'7YXq9G'),
|
||||
(('ffffffff',20),'111111111111117YXq9G'),
|
||||
(('ff'*16,'seed'),'YcVfxkQb6JRzqk5kF2tNLv'),
|
||||
(('ff'*24,'seed'),'QLbz7JHiBTspS962RLKV8GndWFwiEaqKL'),
|
||||
(('ff'*32,'seed'),'JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG'),
|
||||
(('00'*16,'seed'),'1111111111111111111111'),
|
||||
(('00'*24,'seed'),'111111111111111111111111111111111'),
|
||||
(('00'*32,'seed'),'11111111111111111111111111111111111111111111'),
|
||||
),
|
||||
# MMGen-flavored base32 using simple base conversion
|
||||
'b32': (
|
||||
(('00',None),''),
|
||||
(('00',None),'A'),
|
||||
(('00',1),'A'),
|
||||
(('00',2),'AA'),
|
||||
(('01',None),'B'),
|
||||
|
|
@ -39,13 +45,13 @@ class unit_test(object):
|
|||
(('0f',2),'AP'),
|
||||
(('deadbeef',None),'DPK3PXP'),
|
||||
(('deadbeef',20),'AAAAAAAAAAAAADPK3PXP'),
|
||||
(('00000000',None),''),
|
||||
(('00000000',None),'A'),
|
||||
(('00000000',20),'AAAAAAAAAAAAAAAAAAAA'),
|
||||
(('ffffffff',None),'D777777'),
|
||||
(('ffffffff',20),'AAAAAAAAAAAAAD777777'),
|
||||
),
|
||||
'b16': (
|
||||
(('00',None),''),
|
||||
(('00',None),'0'),
|
||||
(('00',1),'0'),
|
||||
(('00',2),'00'),
|
||||
(('01',None),'1'),
|
||||
|
|
@ -56,13 +62,13 @@ class unit_test(object):
|
|||
(('0f',2),'0f'),
|
||||
(('deadbeef',None),'deadbeef'),
|
||||
(('deadbeef',20),'000000000000deadbeef'),
|
||||
(('00000000',None),''),
|
||||
(('00000000',None),'0'),
|
||||
(('00000000',20),'00000000000000000000'),
|
||||
(('ffffffff',None),'ffffffff'),
|
||||
(('ffffffff',20),'000000000000ffffffff'),
|
||||
),
|
||||
'b10': (
|
||||
(('00',None),''),
|
||||
(('00',None),'0'),
|
||||
(('00',1),'0'),
|
||||
(('00',2),'00'),
|
||||
(('01',None),'1'),
|
||||
|
|
@ -73,13 +79,13 @@ class unit_test(object):
|
|||
(('0f',2),'15'),
|
||||
(('deadbeef',None),'3735928559'),
|
||||
(('deadbeef',20),'00000000003735928559'),
|
||||
(('00000000',None),''),
|
||||
(('00000000',None),'0'),
|
||||
(('00000000',20),'00000000000000000000'),
|
||||
(('ffffffff',None),'4294967295'),
|
||||
(('ffffffff',20),'00000000004294967295'),
|
||||
),
|
||||
'b8': (
|
||||
(('00',None),''),
|
||||
(('00',None),'0'),
|
||||
(('00',1),'0'),
|
||||
(('00',2),'00'),
|
||||
(('01',None),'1'),
|
||||
|
|
@ -90,7 +96,7 @@ class unit_test(object):
|
|||
(('0f',2),'17'),
|
||||
(('deadbeef',None),'33653337357'),
|
||||
(('deadbeef',20),'00000000033653337357'),
|
||||
(('00000000',None),''),
|
||||
(('00000000',None),'0'),
|
||||
(('00000000',20),'00000000000000000000'),
|
||||
(('ffffffff',None),'37777777777'),
|
||||
(('ffffffff',20),'00000000037777777777'),
|
||||
|
|
@ -106,32 +112,62 @@ class unit_test(object):
|
|||
rerr = "return value ({!r}) does not match reference value ({!r})"
|
||||
|
||||
qmsg_r('\nChecking hex-to-base conversion:')
|
||||
fs = " {h:10} {p:6} {r}"
|
||||
for base,data in self.vectors.items():
|
||||
fs = " {h:%s} {p:<6} {r}" % max(len(d[0][0]) for d in data)
|
||||
if not opt.verbose: qmsg_r(' {}'.format(base))
|
||||
vmsg('\nBase: {}'.format(base))
|
||||
vmsg(fs.format(h='Input',p='Pad',r='Output'))
|
||||
for (hexstr,pad),ret_chk in data:
|
||||
ret = baseconv.fromhex(hexstr,wl_id=base,pad=pad,tostr=True)
|
||||
assert len(ret) >= (pad or 0), perr.format(ret,pad)
|
||||
if pad != 'seed':
|
||||
assert len(ret) >= (pad or 0), perr.format(ret,pad)
|
||||
assert ret == ret_chk, rerr.format(ret,ret_chk)
|
||||
vmsg(fs.format(h=hexstr,r=ret,p=str(pad)))
|
||||
# msg("(('{h}',{p}),'{r}'),".format(h=hexstr,r=ret,c=ret_chk,p=pad))
|
||||
# msg('')
|
||||
# return True
|
||||
qmsg_r('\nChecking base-to-hex conversion:')
|
||||
fs = " {h:24} {p:<6} {r}"
|
||||
for base,data in self.vectors.items():
|
||||
fs = " {h:%s} {p:<6} {r}" % max(len(d[1]) for d in data)
|
||||
if not opt.verbose: qmsg_r(' {}'.format(base))
|
||||
vmsg('\nBase: {}'.format(base))
|
||||
vmsg(fs.format(h='Input',p='Pad',r='Output'))
|
||||
for (hexstr,pad),ret_chk in data:
|
||||
ret = baseconv.tohex(ret_chk,wl_id=base,pad=len(hexstr))
|
||||
assert ret == hexstr, rerr.format(ret,ret_chk)
|
||||
vmsg(fs.format(h=ret_chk,r=ret,p=len(hexstr)))
|
||||
if type(pad) == int:
|
||||
pad = len(hexstr)
|
||||
ret = baseconv.tohex(ret_chk,wl_id=base,pad=pad)
|
||||
if pad == None:
|
||||
assert int(ret,16) == int(hexstr,16), rerr.format(ret,ret_chk)
|
||||
else:
|
||||
assert ret == hexstr, rerr.format(ret,ret_chk)
|
||||
vmsg(fs.format(h=ret_chk,r=ret,p=str(pad)))
|
||||
# msg("(('{h}',{p}),'{r}'),".format(h=hexstr,r=ret_chk,c=ret_chk,p=pad))
|
||||
|
||||
qmsg('')
|
||||
|
||||
vmsg('')
|
||||
qmsg('Checking error handling:')
|
||||
|
||||
b = baseconv
|
||||
bad_data = (
|
||||
('bad hexstr', 'HexadecimalStringError','not a hexadecimal str', lambda:b.fromhex('x','b58')),
|
||||
('empty hexstr', 'HexadecimalStringError','empty hex strings not', lambda:b.fromhex('','b58')),
|
||||
('bad b58 data', 'BaseConversionError', 'not in b58', lambda:b.tohex('IfFzZ','b58')),
|
||||
('empty b58 data', 'BaseConversionError', 'empty b58 data', lambda:b.tohex('','b58')),
|
||||
('empty b8 data' , 'BaseConversionError', 'empty b8 data', lambda:b.tohex('','b8')),
|
||||
('bad b32 data', 'BaseConversionError', 'not in b32', lambda:b.tohex('1az','b32')),
|
||||
('bad pad arg (in)', 'BaseConversionPadError',"illegal value for 'pad'", lambda:b.fromhex('ff','b58',pad='foo')),
|
||||
('bad pad arg (in)', 'BaseConversionPadError',"illegal value for 'pad'", lambda:b.fromhex('ff','b58',pad=False)),
|
||||
('bad pad arg (in)', 'BaseConversionPadError',"illegal value for 'pad'", lambda:b.fromhex('ff','b58',pad=True)),
|
||||
('bad seedlen (in)', 'SeedLengthError', "invalid seed byte length",lambda:b.fromhex('ff','b58',pad='seed')),
|
||||
('bad pad arg (out)','BaseConversionPadError',"illegal value for 'pad'", lambda:b.tohex('Z','b58',pad='foo')),
|
||||
('bad pad arg (out)','BaseConversionPadError',"illegal value for 'pad'", lambda:b.tohex('Z','b58',pad=False)),
|
||||
('bad pad arg (out)','BaseConversionPadError',"illegal value for 'pad'", lambda:b.tohex('Z','b58',pad=True)),
|
||||
('bad seedlen (out)','BaseConversionError', "invalid length for seed", lambda:b.tohex('Z','b58',pad='seed')),
|
||||
)
|
||||
|
||||
ut.process_bad_data(bad_data)
|
||||
|
||||
msg('OK')
|
||||
|
||||
return True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue