Thursday, November 29, 2012

Some identities for Python int.to_bytes and int.from_bytes

I read the documentation for int.to_bytes and int.from_bytes and thought that what was missing was a description of what they did in terms of other Python code, rather like what is done for several of the generators in the docs for the itertools module; (I was completing this RC task at the time).

I came up with the following code snippet that I would have found helpful and that I hope helps you.


>>> n = 2491969579123783355964723219455906992268673266682165637887
>>> length = 25
>>> n2bytesbig    = n.to_bytes(length, 'big')
>>> n2byteslittle = n.to_bytes(length, 'little')
>>> assert n2bytesbig    == bytes( (n >> i*8) & 0xff for i in reversed(range(length)))
>>> assert n2byteslittle == bytes( (n >> i*8) & 0xff for i in range(length))
>>> assert n == sum( n2bytesbig[::-1][i] << i*8 for i in range(length) )
>>> assert n == sum( n2byteslittle[i]    << i*8 for i in range(length) )
>>> assert n == int.from_bytes(n2bytesbig,    byteorder='big')
>>> assert n == int.from_bytes(n2byteslittle, byteorder='little')
>>>


3 comments:

  1. Hi Paddy,

    I'm using your algorithm for bitcoin address validation from Rosetta Stone and run into trouble.

    It accepts the following as correct addresses:
    '14oLvT2', # padding omitted
    '111111111111111111114oLvT2', # padding too short
    'miwxGypTcHDXT3m4avmrMMC4co7XWqbG9r', # invalid first character

    Now I wonder, how did you come to the length of 25 in de decode call?

    Kind regards, Robert

    ReplyDelete
  2. Hi Paddy, I made a github repo for this: https://github.com/nederhoed/python-bitcoinadress

    And added an important extra validation: by rehashing the bytearray, you should be able to recreate the address that's being checked. If the checksum is OK, but the original address does not match with the re-base58-encoded string, the address is invalid.

    This is the case for a zero-padded checksum, that should be one-padded in the address. For example: `14oLvT2` has a valid checksum, but is not a valid address. The valid version would be `1111111111111111111114oLvT2`.

    I added it to pypi: http://pypi.python.org/pypi/python-bitcoinaddress
    $ sudo pip install bitcoin-address

    Please review the code and give feedback. That would be highly appreciated!

    ReplyDelete