go-ethereum/rlp.py

58 lines
1.6 KiB
Python
Raw Normal View History

2013-12-19 12:38:09 -06:00
def binary_length(n):
if n == 0: return 0
else: return 1 + binary_length(n / 256)
def to_binary_array(n,L=None):
if L is None: L = binary_length(n)
if n == 0: return []
else:
x = to_binary_array(n / 256)
x.append(n % 256)
return x
def to_binary(n,L=None): return ''.join([chr(x) for x in to_binary_array(n,L)])
def from_binary(b):
if len(b) == 0: return 0
2013-12-21 20:20:30 -06:00
else: return from_binary(b[:-1]) * 256 + ord(b[-1])
2013-12-19 12:38:09 -06:00
def num_to_var_int(n):
2013-12-21 20:20:30 -06:00
if n < 253: s = [n]
elif n < 2**16: s = [253] + list(to_binary_array(n,2))
elif n < 2**32: s = [254] + list(to_binary_array(n,4))
elif n < 2**64: s = [255] + list(to_binary_array(n,8))
else: raise Exception("number too big")
2013-12-19 12:38:09 -06:00
return ''.join([chr(x) for x in s])
2013-12-21 20:20:30 -06:00
def __decode(s):
if s == '': return None
2013-12-19 12:38:09 -06:00
o = []
2013-12-21 20:20:30 -06:00
index = [0]
2013-12-19 12:38:09 -06:00
def read_var_int():
2013-12-21 20:20:30 -06:00
si = ord(s[index[0]])
index[0] += 1
if si < 253: return si
2013-12-19 12:38:09 -06:00
elif si == 253: read = 2
elif si == 254: read = 4
elif si == 255: read = 8
2013-12-21 20:20:30 -06:00
index[0] += read
return from_binary(s[index[0]-read:index[0]])
while index[0] < len(s):
tp = s[index[0]]
index[0] += 1
2013-12-19 12:38:09 -06:00
L = read_var_int()
2013-12-21 20:20:30 -06:00
item = s[index[0]:index[0]+L]
if tp == '\x00': o.append(item)
else: o.append(__decode(item))
index[0] += L
2013-12-19 12:38:09 -06:00
return o
2013-12-21 20:20:30 -06:00
def decode(s): return __decode(s)[0]
2013-12-19 12:38:09 -06:00
def encode(s):
if isinstance(s,(int,long)): return encode(to_binary(s))
2013-12-21 20:20:30 -06:00
if isinstance(s,str): return '\x00'+num_to_var_int(len(s))+s
2013-12-19 12:38:09 -06:00
else:
x = ''.join([encode(x) for x in s])
2013-12-21 20:20:30 -06:00
return '\x01'+num_to_var_int(len(x))+x