Python 'long' object has no attribute 'to_bytes'?
Question:
I’m trying to use a bitcoin address validator written in Python from here:
This snippet gives me trouble though:
def decode_base58(bc, length):
n = 0
for char in bc:
n = n * 58 + digits58.index(char)
return n.to_bytes(length, 'big')
I understand that n is either an int or a long, but neither has a method called to_bytes, so I don’t really understand how this code could have ever worked?
Does anybody know what’s wrong here? Am I doing something wrong, or is this code simply written wrong? All tips are welcome!
Answers:
Since Python 3.2 the built-in integer types provide a to_bytes
method.
https://docs.python.org/3/library/stdtypes.html#int.to_bytes
Python 2.7 int
and long
don’t have the .to_bytes
method. Python 3.2 int
has the .to_bytes
method.
A workaround for Python 2.x:
>>> length = 10
>>> n = 123456789
>>> ('%%0%dx' % (length << 1) % n).decode('hex')[-length:]
'x00x00x00x00x00x00x07[xcdx15'
The code you linked contains :
assert n.to_bytes(length, 'big') == bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
which means that you can define a to_bytes
function:
def to_bytes(n, length):
return bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
And use it as such:
def decode_base58(bc, length):
n = 0
for char in bc:
n = n * 58 + digits58.index(char)
return to_bytes(n, length)
This provided me th required result it was in the comments given by @martineau
''.join(chr((n >> i*8) & 0xff) for i in reversed(range(length)))
I’m trying to use a bitcoin address validator written in Python from here:
This snippet gives me trouble though:
def decode_base58(bc, length):
n = 0
for char in bc:
n = n * 58 + digits58.index(char)
return n.to_bytes(length, 'big')
I understand that n is either an int or a long, but neither has a method called to_bytes, so I don’t really understand how this code could have ever worked?
Does anybody know what’s wrong here? Am I doing something wrong, or is this code simply written wrong? All tips are welcome!
Since Python 3.2 the built-in integer types provide a to_bytes
method.
https://docs.python.org/3/library/stdtypes.html#int.to_bytes
Python 2.7 int
and long
don’t have the .to_bytes
method. Python 3.2 int
has the .to_bytes
method.
A workaround for Python 2.x:
>>> length = 10
>>> n = 123456789
>>> ('%%0%dx' % (length << 1) % n).decode('hex')[-length:]
'x00x00x00x00x00x00x07[xcdx15'
The code you linked contains :
assert n.to_bytes(length, 'big') == bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
which means that you can define a to_bytes
function:
def to_bytes(n, length):
return bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
And use it as such:
def decode_base58(bc, length):
n = 0
for char in bc:
n = n * 58 + digits58.index(char)
return to_bytes(n, length)
This provided me th required result it was in the comments given by @martineau
''.join(chr((n >> i*8) & 0xff) for i in reversed(range(length)))