Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.80 KB | None | 0 0
  1. '''Base58 encoding
  2.  
  3. Implementations of Base58 and Base58Check endcodings that are compatible
  4. with the bitcoin network.
  5. '''
  6.  
  7. # This module is based upon base58 snippets found scattered over many bitcoin
  8. # tools written in python. From what I gather the original source is from a
  9. # forum post by Gavin Andresen, so direct your praise to him.
  10. # This module adds shiny packaging and support for python3.
  11.  
  12. from hashlib import sha256
  13.  
  14. __version__ = '1.0.3'
  15.  
  16. # 58 character alphabet used
  17. alphabet = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  18.  
  19.  
  20. if bytes == str: # python2
  21. iseq, bseq, buffer = (
  22. lambda s: map(ord, s),
  23. lambda s: ''.join(map(chr, s)),
  24. lambda s: s,
  25. )
  26. else: # python3
  27. iseq, bseq, buffer = (
  28. lambda s: s,
  29. bytes,
  30. lambda s: s.buffer,
  31. )
  32.  
  33.  
  34. def scrub_input(v):
  35. if isinstance(v, str) and not isinstance(v, bytes):
  36. v = v.encode('ascii')
  37.  
  38. if not isinstance(v, bytes):
  39. raise TypeError(
  40. "a bytes-like object is required (also str), not '%s'" %
  41. type(v).__name__)
  42.  
  43. return v
  44.  
  45.  
  46. def b58encode_int(i, default_one=True):
  47. '''Encode an integer using Base58'''
  48. if not i and default_one:
  49. return alphabet[0:1]
  50. string = b""
  51. while i:
  52. i, idx = divmod(i, 58)
  53. string = alphabet[idx:idx+1] + string
  54. return string
  55.  
  56.  
  57. def b58encode(v):
  58. '''Encode a string using Base58'''
  59. v = scrub_input(v)
  60.  
  61. nPad = len(v)
  62. v = v.lstrip(b'\0')
  63. nPad -= len(v)
  64.  
  65. p, acc = 1, 0
  66. for c in iseq(reversed(v)):
  67. acc += p * c
  68. p = p << 8
  69.  
  70. result = b58encode_int(acc, default_one=False)
  71.  
  72. return (alphabet[0:1] * nPad + result)
  73.  
  74.  
  75. def b58decode_int(v):
  76. '''Decode a Base58 encoded string as an integer'''
  77. v = v.rstrip()
  78. v = scrub_input(v)
  79.  
  80. decimal = 0
  81. for char in v:
  82. decimal = decimal * 58 + alphabet.index(char)
  83. return decimal
  84.  
  85.  
  86. def b58decode(v):
  87. '''Decode a Base58 encoded string'''
  88. v = v.rstrip()
  89. v = scrub_input(v)
  90.  
  91. origlen = len(v)
  92. v = v.lstrip(alphabet[0:1])
  93. newlen = len(v)
  94.  
  95. acc = b58decode_int(v)
  96.  
  97. result = []
  98. while acc > 0:
  99. acc, mod = divmod(acc, 256)
  100. result.append(mod)
  101.  
  102. return (b'\0' * (origlen - newlen) + bseq(reversed(result)))
  103.  
  104.  
  105. def b58encode_check(v):
  106. '''Encode a string using Base58 with a 4 character checksum'''
  107.  
  108. digest = sha256(sha256(v).digest()).digest()
  109. return b58encode(v + digest[:4])
  110.  
  111.  
  112. def b58decode_check(v):
  113. '''Decode and verify the checksum of a Base58 encoded string'''
  114.  
  115. result = b58decode(v)
  116. result, check = result[:-4], result[-4:]
  117. digest = sha256(sha256(result).digest()).digest()
  118.  
  119. if check != digest[:4]:
  120. raise ValueError("Invalid checksum")
  121.  
  122. return result
  123.  
  124.  
  125. def main():
  126. '''Base58 encode or decode FILE, or standard input, to standard output.'''
  127.  
  128. import sys
  129. import argparse
  130.  
  131. stdout = buffer(sys.stdout)
  132.  
  133. parser = argparse.ArgumentParser(description=main.__doc__)
  134. parser.add_argument(
  135. 'file',
  136. metavar='FILE',
  137. nargs='?',
  138. type=argparse.FileType('r'),
  139. default='-')
  140. parser.add_argument(
  141. '-d', '--decode',
  142. action='store_true',
  143. help='decode data')
  144. parser.add_argument(
  145. '-c', '--check',
  146. action='store_true',
  147. help='append a checksum before encoding')
  148.  
  149. args = parser.parse_args()
  150. fun = {
  151. (False, False): b58encode,
  152. (False, True): b58encode_check,
  153. (True, False): b58decode,
  154. (True, True): b58decode_check
  155. }[(args.decode, args.check)]
  156.  
  157. data = buffer(args.file).read()
  158.  
  159. try:
  160. result = fun(data)
  161. except Exception as e:
  162. sys.exit(e)
  163.  
  164. if not isinstance(result, bytes):
  165. result = result.encode('ascii')
  166.  
  167. stdout.write(result)
  168.  
  169.  
  170. if __name__ == '__main__':
  171. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement