Python base 36 encoding

前端 未结 9 940
春和景丽
春和景丽 2020-11-29 03:21

How can I encode an integer with base 36 in Python and then decode it again?

相关标签:
9条回答
  • 2020-11-29 03:46

    I wish I had read this before. Here is the answer:

    def base36encode(number):
        if not isinstance(number, (int, long)):
            raise TypeError('number must be an integer')
        if number < 0:
            raise ValueError('number must be positive')
    
        alphabet, base36 = ['0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', '']
    
        while number:
            number, i = divmod(number, 36)
            base36 = alphabet[i] + base36
    
        return base36 or alphabet[0]
    
    
    def base36decode(number):
        return int(number, 36)
    
    print(base36encode(1412823931503067241))
    print(base36decode('AQF8AA0006EH'))
    
    0 讨论(0)
  • 2020-11-29 03:46

    You can use numpy's base_repr(...) for this.

    import numpy as np
    
    num = 2017
    
    num = np.base_repr(num, 36)
    print(num)  # 1K1
    
    num = int(num, 36)
    print(num)  # 2017
    

    Here is some information about numpy, int(x, base=10), and np.base_repr(number, base=2, padding=0).

    (This answer was originally submitted as an edit to @christopher-beland's answer, but was rejected in favor of its own answer.)

    0 讨论(0)
  • 2020-11-29 03:47

    Have you tried Wikipedia's sample code?

    def base36encode(number, alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
        """Converts an integer to a base36 string."""
        if not isinstance(number, (int, long)):
            raise TypeError('number must be an integer')
    
        base36 = ''
        sign = ''
    
        if number < 0:
            sign = '-'
            number = -number
    
        if 0 <= number < len(alphabet):
            return sign + alphabet[number]
    
        while number != 0:
            number, i = divmod(number, len(alphabet))
            base36 = alphabet[i] + base36
    
        return sign + base36
    
    def base36decode(number):
        return int(number, 36)
    
    print base36encode(1412823931503067241)
    print base36decode('AQF8AA0006EH')
    
    0 讨论(0)
  • 2020-11-29 03:47

    This works if you only care about positive integers.

    def int_to_base36(num):
        """Converts a positive integer into a base36 string."""
        assert num >= 0
        digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    
        res = ''
        while not res or num > 0:
            num, i = divmod(num, 36)
            res = digits[i] + res
        return res
    

    To convert back to int, just use int(num, 36). For a conversion of arbitrary bases see https://gist.github.com/mbarkhau/1b918cb3b4a2bdaf841c

    0 讨论(0)
  • 2020-11-29 03:51

    I benchmarked the example encoders provided in answers to this question. On my Ubuntu 18.10 laptop, Python 3.7, Jupyter, the %%timeit magic command, and the integer 4242424242424242 as the input, I got these results:

    • Wikipedia's sample code: 4.87 µs ± 300 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    • @mistero's base36encode(): 3.62 µs ± 44.2 ns per loop
    • @user1036542's int2base: 10 µs ± 400 ns per loop (after fixing py37 compatibility)
    • @mbarkhau's int_to_base36(): 3.83 µs ± 28.8 ns per loop

    All timings were mean ± std. dev. of 7 runs, 100000 loops each.

    0 讨论(0)
  • 2020-11-29 03:53

    You could use https://github.com/tonyseek/python-base36.

    $ pip install base36
    

    and then

    >>> import base36
    >>> assert base36.dumps(19930503) == 'bv6h3'
    >>> assert base36.loads('bv6h3') == 19930503
    
    0 讨论(0)
提交回复
热议问题