Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the '0z' bug in linux #17

Closed
wants to merge 7 commits into from
Closed

Fix the '0z' bug in linux #17

wants to merge 7 commits into from

Conversation

UnknownObject000
Copy link

@UnknownObject000 UnknownObject000 commented Oct 9, 2019

I use this in linux,its 'encodebytes' function can work,but when I use the 'decodebytes' function,it cause errors as follows.

File "/data/data/com.termux/files/usr/lib/python3.7/site-packages/base62.py", line 95, in decodebytes
    decoded = decode(s, charset=charset)
  File "/data/data/com.termux/files/usr/lib/python3.7/site-packages/base62.py", line 77, in decode
    if b.startswith('0z'):
TypeError: startswith first arg must be bytes or a tuple of bytes, not str

I changed the 'base62.py' file,and it works.

@coveralls
Copy link

Coverage Status

Coverage decreased (-4.4%) to 93.86% when pulling cd52f77 on master into a9b9e7e on develop.

@UnknownObject000
Copy link
Author

UnknownObject000 commented Oct 9, 2019

I want to add the new 'base62.py' in this pull request,but I can't.Here are the source code.

# -*- coding: utf-8 -*-
"""
base62
~~~~~~

Originated from http://blog.suminb.com/archives/558
"""

__title__ = 'base62'
__author__ = 'Sumin Byeon'
__email__ = 'suminb@gmail.com'
__version__ = '0.4.1'

BASE = 62
CHARSET_DEFAULT = (
    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
)
CHARSET_INVERTED = (
    '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
)


def bytes_to_int(s, byteorder='big', signed=False):
    """Converts a byte array to an integer value.

    Python 3 comes with a built-in function to do this, but we would like to
    keep our code Python 2 compatible.
    """

    try:
        return int.from_bytes(s, byteorder, signed=signed)
    except AttributeError:
        # For Python 2.x
        if byteorder != 'big' or signed:
            raise NotImplementedError()

        # NOTE: This won't work if a generator is given
        n = len(s)
        ds = (x << (8 * (n - 1 - i)) for i, x in enumerate(bytearray(s)))

        return sum(ds)


def encode(n, minlen=1, charset=CHARSET_DEFAULT):
    """Encodes a given integer ``n``."""

    chs = []
    while n > 0:
        r = n % BASE
        n //= BASE

        chs.append(charset[r])

    if len(chs) > 0:
        chs.reverse()
    else:
        chs.append('0')

    s = ''.join(chs)
    s = charset[0] * max(minlen - len(s), 0) + s
    return s


def encodebytes(s, charset=CHARSET_DEFAULT):
    """Encodes a bytestring into a base62 string.

    :param s: A byte array
    """

    _check_bytes_type(s)
    return encode(bytes_to_int(s), charset=charset)


def decode(b, charset=CHARSET_DEFAULT):
    """Decodes a base62 encoded value ``b``."""

    if b.startswith(b'0z'):
        b = b[2:]

    l, i, v = len(b), 0, 0
    for x in b:
        v += _value(x, charset=charset) * (BASE ** (l - (i + 1)))
        i += 1

    return v


def decodebytes(s, charset=CHARSET_DEFAULT):
    """Decodes a string of base62 data into a bytes object.

    :param s: A string to be decoded in base62
    :rtype: bytes
    """

    decoded = decode(s, charset=charset)
    buf = bytearray()
    while decoded > 0:
        buf.append(decoded & 0xff)
        decoded //= 256
    buf.reverse()

    return bytes(buf)


def _value(ch, charset):
    """Decodes an individual digit of a base62 encoded string."""

    try:
        return charset.index(chr(ch))
        #return charset[ch]
    except ValueError:
        raise ValueError('base62: Invalid character (%s)' % ch)


def _check_bytes_type(s):
    """Checks if the input is in an appropriate type."""

    if not isinstance(s, bytes):
        msg = 'expected bytes-like object, not %s' % s.__class__.__name__
        raise TypeError(msg)

@suminb
Copy link
Owner

suminb commented Oct 9, 2019

decodebytes() decodes str into bytes. Would you be able to share your code that causes the issue you described?

@UnknownObject000
Copy link
Author

UnknownObject000 commented Oct 9, 2019

Here are my code.By the way,it works fine in Windows10,python 3.7.4.

import base62

def EncodeBase62(string):
    return base62.encodebytes(string.encode('utf-8'))

def DecodeBase62(string):
    return str(base62.decodebytes(string.encode('utf-8')),'utf-8')

if __name__ == "__main__":
    cmd=input("Task(\"1\" for encode and \"2\" for decode):")
    string=input("Input string:")
    if cmd == "1":
        print("Base62 code:",EncodeBase62(string))
    if cmd == "2":
        print("Decoded str:",DecodeBase62(string))

@suminb
Copy link
Owner

suminb commented Oct 9, 2019

decodebytes() is expected to take str types as an input. In your case, it should've been base62.decodebytes(string), assuming string is a str type. I understand their namings could be somewhat confusing, but they are intended to be communicative, so that they hold the following relationships:

  • value == encodebytes(decodebytes(value))
  • value == decodebytes(encodebytes(value))

I've added some documentations in README.rst. You may also refer the latest documentation on https://pypi.org/project/pybase62/ or https://github.com/suminb/base62/blob/develop/README.rst. See the bottom part of the Usage section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants