Port base62 to Python 3.

This commit is contained in:
Itamar Turner-Trauring 2020-07-14 10:51:31 -04:00
parent b1e732fb9a
commit 9c428be0e2
3 changed files with 30 additions and 16 deletions

View File

@ -25,7 +25,7 @@ from hypothesis import (
from allmydata.util import base62, mathutil
def insecurerandstr(n):
return b''.join(map(byteschr, map(random.randrange, [0]*n, [256]*n)))
return bytes(list(map(random.randrange, [0]*n, [256]*n)))
class T(unittest.TestCase):
def _test_num_octets_that_encode_to_this_many_chars(self, chars, octets):
@ -77,7 +77,7 @@ class T(unittest.TestCase):
bs = insecurerandstr(numos)
# zero-out unused least-sig bits
if lib%8:
b=ord(bs[-1])
b = ord(bs[-1:])
b = b >> (8 - (lib%8))
b = b << (8 - (lib%8))
bs = bs[:-1] + byteschr(b)

View File

@ -16,6 +16,7 @@ if PY2:
# Keep these sorted alphabetically, to reduce merge conflicts:
PORTED_MODULES = [
"allmydata.util.assertutil",
"allmydata.util.base62",
"allmydata.util.deferredutil",
"allmydata.util.humanreadable",
"allmydata.util.mathutil",
@ -25,6 +26,7 @@ PORTED_MODULES = [
]
PORTED_TEST_MODULES = [
"allmydata.test.test_base62",
"allmydata.test.test_deferredutil",
"allmydata.test.test_humanreadable",
"allmydata.test.test_python3",

View File

@ -1,16 +1,24 @@
# from the Python Standard Library
import string
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from past.builtins import chr as byteschr
from allmydata.util.mathutil import log_ceil, log_floor
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
chars = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
BASE62CHAR = '[' + chars + ']'
BASE62CHAR = b'[' + chars + b']'
vals = ''.join([chr(i) for i in range(62)])
c2vtranstable = string.maketrans(chars, vals)
v2ctranstable = string.maketrans(vals, chars)
identitytranstable = string.maketrans(chars, chars)
vals = b''.join([byteschr(i) for i in range(62)])
c2vtranstable = bytes.maketrans(chars, vals)
v2ctranstable = bytes.maketrans(vals, chars)
identitytranstable = bytes.maketrans(chars, chars)
def b2a(os):
"""
@ -47,7 +55,9 @@ def b2a_l(os, lengthinbits):
@return the contents of os in base-62 encoded form
"""
os = [ord(o) for o in reversed(os)] # treat os as big-endian -- and we want to process the least-significant o first
# We call bytes() again for Python 2, to ensure literals are using future's
# Python 3-compatible variant.
os = [o for o in reversed(bytes(os))] # treat os as big-endian -- and we want to process the least-significant o first
value = 0
numvalues = 1 # the number of possible values that value could be
@ -62,7 +72,7 @@ def b2a_l(os, lengthinbits):
value //= 62
numvalues //= 62
return string.translate(''.join([chr(c) for c in reversed(chars)]), v2ctranstable) # make it big-endian
return bytes.translate(bytes([c for c in reversed(chars)]), v2ctranstable) # make it big-endian
def num_octets_that_encode_to_this_many_chars(numcs):
return log_floor(62**numcs, 256)
@ -91,7 +101,9 @@ def a2b_l(cs, lengthinbits):
@return the data encoded in cs
"""
cs = [ord(c) for c in reversed(string.translate(cs, c2vtranstable))] # treat cs as big-endian -- and we want to process the least-significant c first
# We call bytes() again for Python 2, to ensure literals are using future's
# Python 3-compatible variant.
cs = [c for c in reversed(bytes(bytes.translate(cs, c2vtranstable)))] # treat cs as big-endian -- and we want to process the least-significant c first
value = 0
numvalues = 1 # the number of possible values that value could be
@ -101,10 +113,10 @@ def a2b_l(cs, lengthinbits):
numvalues *= 62
numvalues = 2**lengthinbits
bytes = []
result_bytes = []
while numvalues > 1:
bytes.append(value % 256)
result_bytes.append(value % 256)
value //= 256
numvalues //= 256
return ''.join([chr(b) for b in reversed(bytes)]) # make it big-endian
return bytes([b for b in reversed(result_bytes)]) # make it big-endian