Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-base58 for openSUSE:Factory checked in at 2021-10-16 22:47:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-base58 (Old) and /work/SRC/openSUSE:Factory/.python-base58.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-base58" Sat Oct 16 22:47:11 2021 rev:4 rq:925620 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-base58/python-base58.changes 2020-07-26 16:19:28.924816035 +0200 +++ /work/SRC/openSUSE:Factory/.python-base58.new.1890/python-base58.changes 2021-10-16 22:47:46.512698743 +0200 @@ -1,0 +2,16 @@ +Mon Aug 30 14:10:48 UTC 2021 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- Update to 2.1.0 + * Parametrise a few tests over alphabet (@keis) + * Made it handle any base with passing alphabet. (#63) (@tanupoo) + * Setup cfg (@keis) + * Add support to ppc64le (@gururajrkatti) + * Update README.md (@alloyxrp) + * New alias for XRP alphabet (@alloyxrp) + * Improve invalid character message (@keis) + * Autofix for similar letters (@keis) + * Add performance benchmarks using pytest-benchmark (@keis) + * Performance optimizations (@kolomenkin) +- Update BuildRequires from setup.cfg + +------------------------------------------------------------------- Old: ---- base58-2.0.1.tar.gz New: ---- base58-2.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-base58.spec ++++++ --- /var/tmp/diff_new_pack.96IBmr/_old 2021-10-16 22:47:46.936699100 +0200 +++ /var/tmp/diff_new_pack.96IBmr/_new 2021-10-16 22:47:46.936699100 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-base58 # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,20 +19,21 @@ %define skip_python2 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-base58 -Version: 2.0.1 +Version: 2.1.0 Release: 0 Summary: Base58 and Base58Check implementation License: MIT Group: Development/Languages/Python URL: https://github.com/keis/base58 Source: https://files.pythonhosted.org/packages/source/b/base58/base58-%{version}.tar.gz -BuildRequires: %{python_module PyHamcrest} -BuildRequires: %{python_module pytest} +BuildRequires: %{python_module PyHamcrest >= 2.0.2} +BuildRequires: %{python_module pytest >= 4.6} +BuildRequires: %{python_module pytest-benchmark} BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires(post): update-alternatives -Requires(postun): update-alternatives +Requires(postun):update-alternatives BuildArch: noarch %python_subpackages ++++++ base58-2.0.1.tar.gz -> base58-2.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/PKG-INFO new/base58-2.1.0/PKG-INFO --- old/base58-2.0.1/PKG-INFO 2020-06-06 15:23:58.000000000 +0200 +++ new/base58-2.1.0/PKG-INFO 2021-01-09 18:34:08.000000000 +0100 @@ -1,17 +1,77 @@ -Metadata-Version: 1.2 +Metadata-Version: 2.1 Name: base58 -Version: 2.0.1 -Summary: Base58 and Base58Check implementation +Version: 2.1.0 +Summary: Base58 and Base58Check implementation. Home-page: https://github.com/keis/base58 Author: David Keijser Author-email: keij...@gmail.com License: MIT -Description: UNKNOWN +Description: # base58 + + [![PyPI Version][pypi-image]](https://pypi.python.org/pypi?name=base58&:action=display) + [![PyPI Downloads][pypi-downloads-image]](https://pypi.python.org/pypi?name=base58&:action=display) + [![Build Status][travis-image]](https://travis-ci.org/keis/base58) + [![Coverage Status][coveralls-image]](https://coveralls.io/r/keis/base58?branch=master) + + Base58 and Base58Check implementation compatible with what is used by the + bitcoin network. Any other alternative alphabet (like the XRP one) can be used. + + Starting from version 2.0.0 **python2 is no longer supported** the 1.x series + will remain supported but no new features will be added. + + + ## Command line usage + + $ printf "hello world" | base58 + StV1DL6CwTryKyV + + $ printf "hello world" | base58 -c + 3vQB7B6MrGQZaxCuFg4oh + + $ printf "3vQB7B6MrGQZaxCuFg4oh" | base58 -dc + hello world + + $ printf "4vQB7B6MrGQZaxCuFg4oh" | base58 -dc + Invalid checksum + + + ## Module usage + + >>> import base58 + >>> base58.b58encode(b'hello world') + b'StV1DL6CwTryKyV' + >>> base58.b58decode(b'StV1DL6CwTryKyV') + b'hello world' + >>> base58.b58encode_check(b'hello world') + b'3vQB7B6MrGQZaxCuFg4oh' + >>> base58.b58decode_check(b'3vQB7B6MrGQZaxCuFg4oh') + b'hello world' + >>> base58.b58decode_check(b'4vQB7B6MrGQZaxCuFg4oh') + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "base58.py", line 89, in b58decode_check + raise ValueError("Invalid checksum") + ValueError: Invalid checksum + # Use another alphabet. Here, using the built-in XRP/Ripple alphabet. + # RIPPLE_ALPHABET is provided as an option for compatibility with existing code + # It is recommended to use XRP_ALPHABET instead + >>> base58.b58encode(b'hello world', alphabet=base58.XRP_ALPHABET) + b'StVrDLaUATiyKyV' + >>> base58.b58decode(b'StVrDLaUATiyKyV', alphabet=base58.XRP_ALPHABET) + b'hello world' + + + [pypi-image]: https://img.shields.io/pypi/v/base58.svg?style=flat + [pypi-downloads-image]: https://img.shields.io/pypi/dm/base58.svg?style=flat + [travis-image]: https://img.shields.io/travis/keis/base58.svg?style=flat + [coveralls-image]: https://img.shields.io/coveralls/keis/base58.svg?style=flat + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Requires-Python: >=3.5 +Description-Content-Type: text/markdown +Provides-Extra: tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/README.md new/base58-2.1.0/README.md --- old/base58-2.0.1/README.md 2020-01-14 18:02:33.000000000 +0100 +++ new/base58-2.1.0/README.md 2021-01-09 17:30:06.000000000 +0100 @@ -6,7 +6,7 @@ [![Coverage Status][coveralls-image]](https://coveralls.io/r/keis/base58?branch=master) Base58 and Base58Check implementation compatible with what is used by the -bitcoin network. Any other alternative alphabet (like the Ripple one) can be used. +bitcoin network. Any other alternative alphabet (like the XRP one) can be used. Starting from version 2.0.0 **python2 is no longer supported** the 1.x series will remain supported but no new features will be added. @@ -44,10 +44,12 @@ File "base58.py", line 89, in b58decode_check raise ValueError("Invalid checksum") ValueError: Invalid checksum - # Use another alphabet. Here, using the built-in Ripple alphabet. - >>> base58.b58encode(b'hello world', alphabet=base58.RIPPLE_ALPHABET) + # Use another alphabet. Here, using the built-in XRP/Ripple alphabet. + # RIPPLE_ALPHABET is provided as an option for compatibility with existing code + # It is recommended to use XRP_ALPHABET instead + >>> base58.b58encode(b'hello world', alphabet=base58.XRP_ALPHABET) b'StVrDLaUATiyKyV' - >>> base58.b58decode(b'StVrDLaUATiyKyV', alphabet=base58.RIPPLE_ALPHABET) + >>> base58.b58decode(b'StVrDLaUATiyKyV', alphabet=base58.XRP_ALPHABET) b'hello world' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/base58/__init__.py new/base58-2.1.0/base58/__init__.py --- old/base58-2.0.1/base58/__init__.py 2020-06-06 15:21:37.000000000 +0200 +++ new/base58-2.1.0/base58/__init__.py 2021-01-09 18:26:23.000000000 +0100 @@ -9,15 +9,17 @@ # forum post by Gavin Andresen, so direct your praise to him. # This module adds shiny packaging and support for python3. +from functools import lru_cache from hashlib import sha256 -from typing import Union +from typing import Mapping, Union -__version__ = '2.0.1' +__version__ = '2.1.0' # 58 character alphabet used BITCOIN_ALPHABET = \ b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' RIPPLE_ALPHABET = b'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz' +XRP_ALPHABET = RIPPLE_ALPHABET # Retro compatibility alphabet = BITCOIN_ALPHABET @@ -39,8 +41,9 @@ if not i and default_one: return alphabet[0:1] string = b"" + base = len(alphabet) while i: - i, idx = divmod(i, 58) + i, idx = divmod(i, base) string = alphabet[idx:idx+1] + string return string @@ -53,35 +56,60 @@ """ v = scrub_input(v) - nPad = len(v) + origlen = len(v) v = v.lstrip(b'\0') - nPad -= len(v) + newlen = len(v) + + acc = int.from_bytes(v, byteorder='big') # first byte is most significant - p, acc = 1, 0 - for c in reversed(v): - acc += p * c - p = p << 8 result = b58encode_int(acc, default_one=False, alphabet=alphabet) - return alphabet[0:1] * nPad + result + return alphabet[0:1] * (origlen - newlen) + result + + +@lru_cache() +def _get_base58_decode_map(alphabet: bytes, + autofix: bool) -> Mapping[int, int]: + invmap = {char: index for index, char in enumerate(alphabet)} + + if autofix: + groups = [b'0Oo', b'Il1'] + for group in groups: + pivots = [c for c in group if c in invmap] + if len(pivots) == 1: + for alternative in group: + invmap[alternative] = invmap[pivots[0]] + + return invmap def b58decode_int( - v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET, *, + autofix: bool = False ) -> int: """ Decode a Base58 encoded string as an integer """ - v = v.rstrip() + if b' ' not in alphabet: + v = v.rstrip() v = scrub_input(v) + map = _get_base58_decode_map(alphabet, autofix=autofix) + decimal = 0 - for char in v: - decimal = decimal * 58 + alphabet.index(char) + base = len(alphabet) + try: + for char in v: + decimal = decimal * base + map[char] + except KeyError as e: + raise ValueError( + "Invalid character <{char}>".format(char=chr(e.args[0])) + ) from None return decimal def b58decode( - v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET, *, + autofix: bool = False ) -> bytes: """ Decode a Base58 encoded string @@ -93,7 +121,7 @@ v = v.lstrip(alphabet[0:1]) newlen = len(v) - acc = b58decode_int(v, alphabet=alphabet) + acc = b58decode_int(v, alphabet=alphabet, autofix=autofix) result = [] while acc > 0: @@ -116,11 +144,12 @@ def b58decode_check( - v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET + v: Union[str, bytes], alphabet: bytes = BITCOIN_ALPHABET, *, + autofix: bool = False ) -> bytes: '''Decode and verify the checksum of a Base58 encoded string''' - result = b58decode(v, alphabet=alphabet) + result = b58decode(v, alphabet=alphabet, autofix=autofix) result, check = result[:-4], result[-4:] digest = sha256(sha256(result).digest()).digest() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/base58/__main__.py new/base58-2.1.0/base58/__main__.py --- old/base58-2.0.1/base58/__main__.py 2020-01-14 18:02:33.000000000 +0100 +++ new/base58-2.1.0/base58/__main__.py 2020-08-31 16:22:11.000000000 +0200 @@ -1,10 +1,18 @@ import argparse import sys +from typing import Callable, Dict, Tuple from base58 import b58decode, b58decode_check, b58encode, b58encode_check +_fmap = { + (False, False): b58encode, + (False, True): b58encode_check, + (True, False): b58decode, + (True, True): b58decode_check +} # type: Dict[Tuple[bool, bool], Callable[[bytes], bytes]] -def main(): + +def main() -> None: '''Base58 encode or decode FILE, or standard input, to standard output.''' stdout = sys.stdout.buffer @@ -26,12 +34,7 @@ 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)] + fun = _fmap[(args.decode, args.check)] data = args.file.buffer.read() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/base58.egg-info/PKG-INFO new/base58-2.1.0/base58.egg-info/PKG-INFO --- old/base58-2.0.1/base58.egg-info/PKG-INFO 2020-06-06 15:23:58.000000000 +0200 +++ new/base58-2.1.0/base58.egg-info/PKG-INFO 2021-01-09 18:34:08.000000000 +0100 @@ -1,17 +1,77 @@ -Metadata-Version: 1.2 +Metadata-Version: 2.1 Name: base58 -Version: 2.0.1 -Summary: Base58 and Base58Check implementation +Version: 2.1.0 +Summary: Base58 and Base58Check implementation. Home-page: https://github.com/keis/base58 Author: David Keijser Author-email: keij...@gmail.com License: MIT -Description: UNKNOWN +Description: # base58 + + [![PyPI Version][pypi-image]](https://pypi.python.org/pypi?name=base58&:action=display) + [![PyPI Downloads][pypi-downloads-image]](https://pypi.python.org/pypi?name=base58&:action=display) + [![Build Status][travis-image]](https://travis-ci.org/keis/base58) + [![Coverage Status][coveralls-image]](https://coveralls.io/r/keis/base58?branch=master) + + Base58 and Base58Check implementation compatible with what is used by the + bitcoin network. Any other alternative alphabet (like the XRP one) can be used. + + Starting from version 2.0.0 **python2 is no longer supported** the 1.x series + will remain supported but no new features will be added. + + + ## Command line usage + + $ printf "hello world" | base58 + StV1DL6CwTryKyV + + $ printf "hello world" | base58 -c + 3vQB7B6MrGQZaxCuFg4oh + + $ printf "3vQB7B6MrGQZaxCuFg4oh" | base58 -dc + hello world + + $ printf "4vQB7B6MrGQZaxCuFg4oh" | base58 -dc + Invalid checksum + + + ## Module usage + + >>> import base58 + >>> base58.b58encode(b'hello world') + b'StV1DL6CwTryKyV' + >>> base58.b58decode(b'StV1DL6CwTryKyV') + b'hello world' + >>> base58.b58encode_check(b'hello world') + b'3vQB7B6MrGQZaxCuFg4oh' + >>> base58.b58decode_check(b'3vQB7B6MrGQZaxCuFg4oh') + b'hello world' + >>> base58.b58decode_check(b'4vQB7B6MrGQZaxCuFg4oh') + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "base58.py", line 89, in b58decode_check + raise ValueError("Invalid checksum") + ValueError: Invalid checksum + # Use another alphabet. Here, using the built-in XRP/Ripple alphabet. + # RIPPLE_ALPHABET is provided as an option for compatibility with existing code + # It is recommended to use XRP_ALPHABET instead + >>> base58.b58encode(b'hello world', alphabet=base58.XRP_ALPHABET) + b'StVrDLaUATiyKyV' + >>> base58.b58decode(b'StVrDLaUATiyKyV', alphabet=base58.XRP_ALPHABET) + b'hello world' + + + [pypi-image]: https://img.shields.io/pypi/v/base58.svg?style=flat + [pypi-downloads-image]: https://img.shields.io/pypi/dm/base58.svg?style=flat + [travis-image]: https://img.shields.io/travis/keis/base58.svg?style=flat + [coveralls-image]: https://img.shields.io/coveralls/keis/base58.svg?style=flat + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: Natural Language :: English Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Requires-Python: >=3.5 +Description-Content-Type: text/markdown +Provides-Extra: tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/base58.egg-info/SOURCES.txt new/base58-2.1.0/base58.egg-info/SOURCES.txt --- old/base58-2.0.1/base58.egg-info/SOURCES.txt 2020-06-06 15:23:58.000000000 +0200 +++ new/base58-2.1.0/base58.egg-info/SOURCES.txt 2021-01-09 18:34:08.000000000 +0100 @@ -3,6 +3,7 @@ README.md setup.cfg setup.py +test_base45.py test_base58.py base58/__init__.py base58/__main__.py @@ -12,4 +13,5 @@ base58.egg-info/dependency_links.txt base58.egg-info/entry_points.txt base58.egg-info/not-zip-safe +base58.egg-info/requires.txt base58.egg-info/top_level.txt \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/base58.egg-info/requires.txt new/base58-2.1.0/base58.egg-info/requires.txt --- old/base58-2.0.1/base58.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/base58-2.1.0/base58.egg-info/requires.txt 2021-01-09 18:34:08.000000000 +0100 @@ -0,0 +1,8 @@ + +[tests] +pytest>=4.6 +pytest-flake8 +pytest-cov +PyHamcrest>=2.0.2 +coveralls +pytest-benchmark diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/setup.cfg new/base58-2.1.0/setup.cfg --- old/base58-2.0.1/setup.cfg 2020-06-06 15:23:58.000000000 +0200 +++ new/base58-2.1.0/setup.cfg 2021-01-09 18:34:08.000000000 +0100 @@ -1,7 +1,45 @@ [bumpversion] -current_version = 2.0.1 +current_version = 2.1.0 -[bumpversion:file:setup.py] +[metadata] +name = base58 +author = David Keijser +author_email = keij...@gmail.com +version = 2.1.0 +description = Base58 and Base58Check implementation. +long_description = file: README.md +long_description_content_type = text/markdown +url = https://github.com/keis/base58 +license = MIT +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Developers + License :: OSI Approved :: MIT License + Programming Language :: Python + Programming Language :: Python :: 3 + +[options] +packages = base58 +zip_safe = False +python_requires = >=3.5 + +[options.entry_points] +console_scripts = + base58 = base58.__main__:main + +[options.package_data] +base58 = py.typed + +[options.extras_require] +tests = + pytest>=4.6 + pytest-flake8 + pytest-cov + PyHamcrest>=2.0.2 + coveralls + pytest-benchmark + +[bumpversion:file:setup.cfg] [bumpversion:file:base58/__init__.py] @@ -16,6 +54,9 @@ [mypy-setuptools.*] ignore_missing_imports = True +[mypy-pytest.*] +ignore_missing_imports = True + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/setup.py new/base58-2.1.0/setup.py --- old/base58-2.0.1/setup.py 2020-06-06 15:21:37.000000000 +0200 +++ new/base58-2.1.0/setup.py 2021-01-09 17:31:18.000000000 +0100 @@ -1,28 +1,3 @@ from setuptools import setup -setup( - name='base58', - packages=['base58'], - package_data={'base58': ['py.typed']}, - version='2.0.1', - description='Base58 and Base58Check implementation', - author='David Keijser', - author_email='keij...@gmail.com', - url='https://github.com/keis/base58', - license='MIT', - zip_safe=False, # mypy needs this to be able to find the package - entry_points={ - 'console_scripts': [ - 'base58 = base58.__main__:main' - ] - }, - python_requires=">=3.5", - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Natural Language :: English', - 'License :: OSI Approved :: MIT License', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - ], -) +setup() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/test_base45.py new/base58-2.1.0/test_base45.py --- old/base58-2.0.1/test_base45.py 1970-01-01 01:00:00.000000000 +0100 +++ new/base58-2.1.0/test_base45.py 2021-01-09 18:26:18.000000000 +0100 @@ -0,0 +1,90 @@ +from hamcrest import assert_that, equal_to, calling, raises +from base58 import (b58encode, b58decode, b58encode_check, b58decode_check) + +BASE45_ALPHABET = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + + +def test_simple_encode(): + data = b58encode(b'hello world', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'K3*J+EGLBVAYYB36')) + + +def test_leadingz_encode(): + data = b58encode(b'\0\0hello world', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'00K3*J+EGLBVAYYB36')) + + +def test_encode_empty(): + data = b58encode(b'', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'')) + + +def test_simple_decode(): + data = b58decode('K3*J+EGLBVAYYB36', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'hello world')) + + +def test_simple_decode_bytes(): + data = b58decode(b'K3*J+EGLBVAYYB36', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'hello world')) + + +def test_autofix_decode_bytes(): + data = b58decode( + b'K3*J+EGLBVAYYB36', alphabet=BASE45_ALPHABET, autofix=True) + assert_that(data, equal_to(b'hello world')) + + +def test_leadingz_decode(): + data = b58decode('00K3*J+EGLBVAYYB36', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'\0\0hello world')) + + +def test_leadingz_decode_bytes(): + data = b58decode(b'00K3*J+EGLBVAYYB36', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'\0\0hello world')) + + +def test_empty_decode(): + data = b58decode('1', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'\x01')) + + +def test_empty_decode_bytes(): + data = b58decode(b'1', alphabet=BASE45_ALPHABET) + assert_that(data, equal_to(b'\x01')) + + +def test_check_str(): + data = 'hello world' + out = b58encode_check(data, alphabet=BASE45_ALPHABET) + assert_that(out, equal_to(b'AHN49RN6G8B%AWUALA8K2D')) + back = b58decode_check(out, alphabet=BASE45_ALPHABET) + assert_that(back, equal_to(b'hello world')) + + +def test_autofix_check_str(): + data = 'AHN49RN6G8B%AWUALA8K2D' + back = b58decode_check(data, alphabet=BASE45_ALPHABET, autofix=True) + assert_that(back, equal_to(b'hello world')) + + +def test_autofix_not_applicable_check_str(): + charset = BASE45_ALPHABET.replace(b'x', b'l') + msg = b'hello world' + enc = b58encode_check(msg, alphabet=BASE45_ALPHABET) + modified = enc.replace(b'x', b'l').replace(b'o', b'0') + back = b58decode_check(modified, alphabet=charset, autofix=True) + assert_that(back, equal_to(msg)) + + +def test_check_failure(): + data = '3vQB7B6MrGQZaxCuFg4oH' + assert_that(calling(b58decode_check).with_args(data), raises(ValueError)) + + +def test_invalid_input(): + data = 'xyz0' # 0 is not part of the bitcoin base58 alphabet + assert_that( + calling(b58decode).with_args(data), + raises(ValueError, 'Invalid character <0>')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/base58-2.0.1/test_base58.py new/base58-2.1.0/test_base58.py --- old/base58-2.0.1/test_base58.py 2020-03-10 18:52:24.000000000 +0100 +++ new/base58-2.1.0/test_base58.py 2021-01-09 18:26:18.000000000 +0100 @@ -1,8 +1,20 @@ +import pytest from itertools import product +from random import getrandbits from hamcrest import assert_that, equal_to, calling, raises from base58 import ( b58encode, b58decode, b58encode_check, b58decode_check, b58encode_int, - b58decode_int, BITCOIN_ALPHABET, alphabet) + b58decode_int, + BITCOIN_ALPHABET, + XRP_ALPHABET) + + +BASE45_ALPHABET = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" + + +@pytest.fixture(params=[BITCOIN_ALPHABET, XRP_ALPHABET, BASE45_ALPHABET]) +def alphabet(request) -> str: + return request.param def test_simple_encode(): @@ -30,6 +42,11 @@ assert_that(data, equal_to(b'hello world')) +def test_autofix_decode_bytes(): + data = b58decode(b'StVlDL6CwTryKyV', autofix=True) + assert_that(data, equal_to(b'hello world')) + + def test_leadingz_decode(): data = b58decode('11StV1DL6CwTryKyV') assert_that(data, equal_to(b'\0\0hello world')) @@ -50,12 +67,6 @@ assert_that(data, equal_to(b'\0')) -def test_check_identity(): - data = b'hello world' - out = b58decode_check(b58encode_check(data)) - assert_that(out, equal_to(data)) - - def test_check_str(): data = 'hello world' out = b58encode_check(data) @@ -64,25 +75,50 @@ assert_that(back, equal_to(b'hello world')) +def test_autofix_check_str(): + data = '3vQB7B6MrGQZaxCuFg4Oh' + back = b58decode_check(data, autofix=True) + assert_that(back, equal_to(b'hello world')) + + +def test_autofix_not_applicable_check_str(): + charset = BITCOIN_ALPHABET.replace(b'x', b'l') + msg = b'hello world' + enc = b58encode_check(msg).replace(b'x', b'l').replace(b'o', b'0') + back = b58decode_check(enc, alphabet=charset, autofix=True) + assert_that(back, equal_to(msg)) + + def test_check_failure(): data = '3vQB7B6MrGQZaxCuFg4oH' assert_that(calling(b58decode_check).with_args(data), raises(ValueError)) -def test_round_trips(): +def test_check_identity(alphabet): + data = b'hello world' + out = b58decode_check( + b58encode_check(data, alphabet=alphabet), + alphabet=alphabet + ) + assert_that(out, equal_to(data)) + + +def test_round_trips(alphabet): possible_bytes = [b'\x00', b'\x01', b'\x10', b'\xff'] for length in range(0, 5): for bytes_to_test in product(possible_bytes, repeat=length): bytes_in = b''.join(bytes_to_test) - bytes_out = b58decode(b58encode(bytes_in)) + bytes_out = b58decode( + b58encode(bytes_in, alphabet=alphabet), + alphabet=alphabet) assert_that(bytes_in, equal_to(bytes_out)) -def test_simple_integers(): - for idx, char in enumerate(BITCOIN_ALPHABET): +def test_simple_integers(alphabet): + for idx, char in enumerate(alphabet): charbytes = bytes([char]) - assert_that(b58decode_int(charbytes), equal_to(idx)) - assert_that(b58encode_int(idx), equal_to(charbytes)) + assert_that(b58decode_int(charbytes, alphabet=alphabet), equal_to(idx)) + assert_that(b58encode_int(idx, alphabet=alphabet), equal_to(charbytes)) def test_large_integer(): @@ -91,5 +127,23 @@ assert_that(b58encode_int(number), equal_to(BITCOIN_ALPHABET[1:])) -def test_alphabet_alias_exists_and_equals_bitcoin_alphabet(): - assert_that(alphabet, equal_to(BITCOIN_ALPHABET)) +def test_invalid_input(): + data = 'xyz0' # 0 is not part of the bitcoin base58 alphabet + assert_that( + calling(b58decode).with_args(data), + raises(ValueError, 'Invalid character <0>')) + + +@pytest.mark.parametrize('length', [8, 32, 256, 1024]) +def test_encode_random(benchmark, length) -> None: + data = getrandbits(length * 8).to_bytes(length, byteorder='big') + encoded = benchmark(lambda: b58encode(data)) + assert_that(b58decode(encoded), equal_to(data)) + + +@pytest.mark.parametrize('length', [8, 32, 256, 1024]) +def test_decode_random(benchmark, length) -> None: + origdata = getrandbits(length * 8).to_bytes(length, byteorder='big') + encoded = b58encode(origdata) + data = benchmark(lambda: b58decode(encoded)) + assert_that(data, equal_to(origdata))