Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- '''Base58 encoding
- Implementations of Base58 and Base58Check endcodings that are compatible
- with the bitcoin network.
- '''
- # This module is based upon base58 snippets found scattered over many bitcoin
- # tools written in python. From what I gather the original source is from a
- # forum post by Gavin Andresen, so direct your praise to him.
- # This module adds shiny packaging and support for python3.
- from hashlib import sha256
- __version__ = '1.0.3'
- # 58 character alphabet used
- alphabet = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
- if bytes == str: # python2
- iseq, bseq, buffer = (
- lambda s: map(ord, s),
- lambda s: ''.join(map(chr, s)),
- lambda s: s,
- )
- else: # python3
- iseq, bseq, buffer = (
- lambda s: s,
- bytes,
- lambda s: s.buffer,
- )
- def scrub_input(v):
- if isinstance(v, str) and not isinstance(v, bytes):
- v = v.encode('ascii')
- if not isinstance(v, bytes):
- raise TypeError(
- "a bytes-like object is required (also str), not '%s'" %
- type(v).__name__)
- return v
- def b58encode_int(i, default_one=True):
- '''Encode an integer using Base58'''
- if not i and default_one:
- return alphabet[0:1]
- string = b""
- while i:
- i, idx = divmod(i, 58)
- string = alphabet[idx:idx+1] + string
- return string
- def b58encode(v):
- '''Encode a string using Base58'''
- v = scrub_input(v)
- nPad = len(v)
- v = v.lstrip(b'\0')
- nPad -= len(v)
- p, acc = 1, 0
- for c in iseq(reversed(v)):
- acc += p * c
- p = p << 8
- result = b58encode_int(acc, default_one=False)
- return (alphabet[0:1] * nPad + result)
- def b58decode_int(v):
- '''Decode a Base58 encoded string as an integer'''
- v = v.rstrip()
- v = scrub_input(v)
- decimal = 0
- for char in v:
- decimal = decimal * 58 + alphabet.index(char)
- return decimal
- def b58decode(v):
- '''Decode a Base58 encoded string'''
- v = v.rstrip()
- v = scrub_input(v)
- origlen = len(v)
- v = v.lstrip(alphabet[0:1])
- newlen = len(v)
- acc = b58decode_int(v)
- result = []
- while acc > 0:
- acc, mod = divmod(acc, 256)
- result.append(mod)
- return (b'\0' * (origlen - newlen) + bseq(reversed(result)))
- def b58encode_check(v):
- '''Encode a string using Base58 with a 4 character checksum'''
- digest = sha256(sha256(v).digest()).digest()
- return b58encode(v + digest[:4])
- def b58decode_check(v):
- '''Decode and verify the checksum of a Base58 encoded string'''
- result = b58decode(v)
- result, check = result[:-4], result[-4:]
- digest = sha256(sha256(result).digest()).digest()
- if check != digest[:4]:
- raise ValueError("Invalid checksum")
- return result
- def main():
- '''Base58 encode or decode FILE, or standard input, to standard output.'''
- import sys
- import argparse
- stdout = buffer(sys.stdout)
- parser = argparse.ArgumentParser(description=main.__doc__)
- parser.add_argument(
- 'file',
- metavar='FILE',
- nargs='?',
- type=argparse.FileType('r'),
- default='-')
- parser.add_argument(
- '-d', '--decode',
- action='store_true',
- help='decode data')
- parser.add_argument(
- '-c', '--check',
- action='store_true',
- help='append a checksum before encoding')
- args = parser.parse_args()
- fun = {
- (False, False): b58encode,
- (False, True): b58encode_check,
- (True, False): b58decode,
- (True, True): b58decode_check
- }[(args.decode, args.check)]
- data = buffer(args.file).read()
- try:
- result = fun(data)
- except Exception as e:
- sys.exit(e)
- if not isinstance(result, bytes):
- result = result.encode('ascii')
- stdout.write(result)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement