keis / base58 Goto Github PK
View Code? Open in Web Editor NEWBase58 and Base58Check implementation compatible with what is used by the bitcoin network.
License: MIT License
Base58 and Base58Check implementation compatible with what is used by the bitcoin network.
License: MIT License
In Python3, b58decode_int
function throws the following error:
Traceback (most recent call last):
File "b58.py", line 13, in <module>
b = base58.b58decode(m)
File "/home/wilson/.local/lib/python3.5/site-packages/base58.py", line 83, in b58decode
acc = b58decode_int(v)
File "/home/wilson/.local/lib/python3.5/site-packages/base58.py", line 69, in b58decode_int
decimal = decimal * 58 + alphabet.index(char)
ValueError: substring not found
Line 69 has shifted to line 83 in current repository.
Fixable by replacing .index()
with .find()
The PyPI release tarball doesn't include tests.
For the moment I use the release from GitHub, but is it possible to include those on PyPI ?
this would work in python3, it should be generalized for python2
# https://en.bitcoin.it/wiki/Wallet_import_format
p = 0xC28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D
uncompressedKey = b'\x80' + p.to_bytes(32, byteorder='big')
uncompressedWIF = '5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ'
compressedKey = b'\x80' + p.to_bytes(32, byteorder='big') + b'\x01'
compressedWIF = 'KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617'
def test_privKey_to_wif():
wif = b58encode_check(uncompressedKey)
assert_that(wif, equal_to(uncompressedWIF))
wif = b58encode_check(compressedKey)
assert_that(wif, equal_to(compressedWIF))
def test_wif_to_privKey():
extKey= b58decode_check(uncompressedWIF)
assert_that(extKey, equal_to(uncompressedKey))
extKey= b58decode_check(compressedWIF)
assert_that(extKey, equal_to(compressedKey))
What is the license for this code? Please consider adding a license file.
import base58
base58.b58decode(b'0e8b9df6a54271ad7e8ec9b58175546d27cbd5c9589ae0683b986b4d484b0b06')
Traceback (most recent call last):
File "", line 1, in
File "base58.py", line 96, in b58decode
acc = b58decode_int(v)
File "base58.py", line 83, in b58decode_int
decimal = decimal * 58 + alphabet.index(char)
ValueError: substring not found
b58encode_check only takes bytes
as input. This is inconsistent with b58encode, which can handle a Union[str, bytes]
as input.
Clearly your project works on python 3 since it is passing tests on Travis in both python 2 and 3. However, the site CanIusePython3 says that this package does not work on python 3. The way to demonstrate python 3 support is documented here, basically you need to pass an appropriate trove classifier in setup.py
, in a classifier
argument to setup()
.
A working example is here.
It would be nice to allow this module to register its functions to the codecs module for easier integration.
https://docs.python.org/2.7/library/codecs.html#codecs.register
https://docs.python.org/3.6/library/codecs.html#codecs.register
Thanks for your work on this library.
I am looking into packaging this library for Debian, and I noticed the fix for #15 has not yet been released under a version number. Would you be able to tag a new version, so I can package a library with the same interface as the base64
standard library package?
The command line program strips trailing newlines from the input data to be encoded:
Line 149 in 24372af
This is not desired because when encoding data, this prevents correct encoding of binary data (such as a HASH160 digest) which can end in a newline char. For example, if I wanted to encode the bitcoin address 1FdHgMWo5rWRDcxp6ygqq64TaWZR9qFzwv, and I fed the codec the pubkeyhash for this address 0xa06ea87a68cc6e0ea5816e9d9cbcd776d07cbd0a
, it would strip the trailing newline byte 0x0a
resulting an a totally incorrect b58check encoded string.
Not quite an issue, given that the library does not advertise base-45 functionality, but perhaps something to keep in mind. The proposed base-45 encodings I'm aware of (main two listed below) are different from the BTC base-58 encoding:
I think the empty byte string b''
should encode to the empty string ""
. Instead, it currently encodes to "11"
.
Similarly, the string "1"
should decode to the byte b'\x00'
. Instead, it currently decodes to b'\x00\x00'
.
I'm not totally sure about the right behavior for Base58 padding, but I think at least it should be possible to round-trip any string of bytes. Right now if you send any number of zero-bytes (including the empty bytestring) through encode+decode, you get a different number of bytes back out.
Hello,
I'm getting this error on Python 3.5.1
TypeError: lstrip arg must be None or str
It's very easy to reproduce it.
import base58
base58.b58encode("test")
currently your encode function spits out a string, which is annoying because I have to wrap the output in the str.encode() method.
The following code has very bad performance for long encoded strings:
It is better to use pre-calculated array to map any possible character to its index in original alphabet.
Original code:
for char in v:
decimal = decimal * 58 + alphabet.index(char)
Possible solution:
import array
map = array.array('b', [alphabet.find(chr(x)) for x in range(256)])
for char in v:
decimal = decimal * 58 + map[ord(char)]
My solution is not ideal for short strings. It is a good idea to have mapping to be pre-calculated for each alphabet.
And original solution was raising exception in case of unexpected character found. New solution will not raise exception but it may be fixed.
Would you like to add some fault tolerance such as automatically change l
to 1
?
Hi,
On line 44, if I change the,
acc, mod = divmod(acc, 58),
into ->
acc = divmod(acc, 58)[0]
mod = divmod(acc, 58)[1]
I get a different result than the once provided in the test.
Is there a reason for this?
I had this issue:
$ echo "23t3yhAuaMWSkzyg5bwpwkcbwDW4b1vT7hKetYNsiW1SrS7kEd2Mz9SCoGM6qQ9QZRTYJUsbxP4U2qnsre3cdjhDBW3rqrhxK5XC12yo1HvujG5envGAyMwf4HpnZ1Z5NWcKkMpERMDpsJ8EbrnqLBTRPxW5UfzZHcvKwayp1KxwSzzwZTb671eSVAZkND4FHJApU1kht88vqitjBHUPp5H" | base58 -d
$ substring not found
But it works with printf:
$ printf "23t3yhAuaMWSkzyg5bwpwkcbwDW4b1vT7hKetYNsiW1SrS7kEd2Mz9SCoGM6qQ9QZRTYJUsbxP4U2qnsre3cdjhDBW3rqrhxK5XC12yo1HvujG5envGAyMwf4HpnZ1Z5NWcKkMpERMDpsJ8EbrnqLBTRPxW5UfzZHcvKwayp1KxwSzzwZTb671eSVAZkND4FHJApU1kht88vqitjBHUPp5H" | base58 -d
$ 3167103626579990164481551900631455406227649498339870931463659678762007414973185848385145925751739606156366598497723358368426602431521721329611646179289862914
Why?
I'm sorry this is more a support request than an issue in the code. Couldn't find a better place to ask about this.
I'm executing this on the command line:
echo "4AfmonCVDRutyt3vMfsooagRsoNXTCVURGZ7nzSZPP9CWykXUmgA72Sfgrne7EcqtVJE6Gq6aA8xw21bHtbZMQzL" | base58 -d
And the output is:
�c�+�w� ���0��s-C��ǂг��) ��3��A@G�w뽝1A楡��Mՙ�#�Y
I'd like to get an array of decimals instead, just like the following code using base58
as a package and not from the command line:
(working example taken from https://stackoverflow.com/a/69256259)
import base58
MY_PRIVATE_KEY_IN_BASE58="4AfmonCVDRutyt3vMfsooagRsoNXTCVURGZ7nzSZPP9CWykXUmgA72Sfgrne7EcqtVJE6Gq6aA8xw21bHtbZMQzL"
byte_array = base58.b58decode(MY_PRIVATE_KEY_IN_BASE58)
json_string = "[" + ",".join(map(lambda b: str(b), byte_array)) + "]"
print(json_string)
Executing that outputs an array of integers:
[158,99,132,43,140,119,254,9,6,225,141,208,225,184,48,219,246,115,45,3,0,67,160,190,25,199,130,208,179,210,219,1,41,32,144,228,51,198,235,65,64,71,155,119,235,189,157,49,2,65,230,165,161,159,153,77,213,153,226,174,35,2,212,89]
Do you know what normal unix/linux command line utility I could use to pipe base58's output into and at least print the list of decimals instead of the gibberish text?
It leads to confusion when trying to figure out why my script was behaving differently.. different versions of the package have the same version property for base58.py
Example code:
>>> b = b'\x00\x81\x1a\xba\x18\x9fB\xee\x9d\xe3\nR2\xf7u\xbc'
>>> i = int(b.hex(), 16)
>>> b58encode(b)
b'14cVa7ENbANHf5WGzDC8VH'
>>> b58encode_int(i)
b'4cVa7ENbANHf5WGzDC8VH'
They decode properly
>>> b58decode(b58encode(b)) == b
True
>>> b58decode_int(b58encode_int(i)) == i
True
From my explorations, the output of b58encode()
and b58encode_int()
only
differs when the byte string has prefix \0
s.
appears the culprit.
The output of b58encode()
and b58encode_int()
should be identical, right?
The code may be simplified using int.from_bytes().
The proposed change makes the code more simple.
And I hope it will become faster.
Original code:
p, acc = 1, 0
for c in reversed(v):
acc += p * c
p = p << 8
My code instead:
acc = int.from_bytes(v, byteorder='big')
I would also propose to rename variable acc
after this change.
This change will need Python 3.2 at least:
https://docs.python.org/3.2/library/stdtypes.html?highlight=set#int.from_bytes
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.