Python基础36编码

时间:2009-07-25 11:32:32

标签: python

如何在Python中用base 36编码一个整数然后再解码?

9 个答案:

答案 0 :(得分:37)

您是否尝试过维基百科的示例代码?

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')

答案 1 :(得分:31)

我希望我之前读过这篇文章。这是答案:

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'))

答案 2 :(得分:19)

from numpy import base_repr

num = base_repr(num, 36)
num = int(num, 36)

以下是有关numpy.base_repr的信息。

答案 3 :(得分:11)

可怕的答案,但只是在玩这个我想分享的想法。

import string, math

int2base = lambda a, b: ''.join(
    [(string.digits +
      string.ascii_lowercase +
      string.ascii_uppercase)[(a // b ** i) % b]
     for i in range(int(math.log(a, b)), -1, -1)]
)

num = 1412823931503067241
test = int2base(num, 36)
test2 = int(test, 36)
print test2 == num

答案 4 :(得分:8)

你可以使用numpy的base_repr(...)

import numpy as np

num = 2017

num = np.base_repr(num, 36)
print(num)  # 1K1

num = int(num, 36)
print(num)  # 2017

以下是有关numpyint(x, base=10)np.base_repr(number, base=2, padding=0)的一些信息。

(这个答案最初是作为@ christopher-beland答案的编辑提交的,但被拒绝支持自己的答案。)

答案 5 :(得分:7)

您可以使用https://github.com/tonyseek/python-base36

$ pip install base36

然后

>>> import base36
>>> assert base36.dumps(19930503) == 'bv6h3'
>>> assert base36.loads('bv6h3') == 19930503

答案 6 :(得分:2)

如果你只关心正整数,这是有效的。

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

要转换回int,只需使用int(num, 36)即可。有关任意碱基的转换,请参阅https://gist.github.com/mbarkhau/1b918cb3b4a2bdaf841c

答案 7 :(得分:1)

我对这个问题的答案中提供的示例编码器进行了基准测试。在我的Ubuntu 18.10笔记本电脑上,Python 3.7,Jupyter,%%timeit魔术命令和整数4242424242424242作为输入,我得到了以下结果:

  • Wikipedia的示例代码: 4.87 µs (每个循环±300 ns)(平均±标准偏差,共运行7次,每个循环100000次)
  • @mistero的base36encode() 3.62 µs (每循环±44.2 ns)
  • @ user1036542的int2base 10 µs (每个循环)±400 ns(修复了py37兼容性之后)
  • @mbarkhau的int_to_base36() 3.83 µs 每个循环±28.8 ns

所有时间均为平均值±标准差。开发。 7次运行,每个运行100000次循环。

答案 8 :(得分:0)

如果您感觉功能正常

def b36_encode(i):
    if i < 0: return "-" + b36_encode(-i)
    if i < 36: return "0123456789abcdefghijklmnopqrstuvwxyz"[i]
    return b36_encode(i // 36) + b36_encode(i % 36)    

测试

n = -919283471029384701938478
s = "-45p3wubacgd6s0fi"
assert int(s, base=36) == n
assert b36_encode(n) == s