Кодировка Python base 36
Как я могу кодировать целое число с основанием 36 в Python, а затем декодировать его снова?
7 ответов
Вы пробовали пример кода Википедии?
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')
Я хотел бы прочитать это раньше. Вот ответ:
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'))
from numpy import base_repr
num = base_repr(num, 36)
num = int(num, 36)
Вот информация о NumPy.
Вы можете использовать Numpy's base_repr(...)
за это.
import numpy as np
num = 2017
num = np.base_repr(num, 36)
print(num) # 1K1
num = int(num, 36)
print(num) # 2017
Вот некоторая информация о NumPy, int(x, base=10)
, а также np.base_repr(number, base=2, padding=0)
,
(Этот ответ первоначально был представлен в виде правки для ответа @christopher-beland, но был отклонен в пользу своего собственного ответа.)
Вы можете использовать https://github.com/tonyseek/python-base36.
$ pip install base36
а потом
>>> import base36
>>> assert base36.dumps(19930503) == 'bv6h3'
>>> assert base36.loads('bv6h3') == 19930503
Ужасный ответ, но я просто играл с этой мыслью, которой я бы поделился.
import string, math
int2base = lambda a, b: ''.join(
[(string.digits + string.lowercase + string.uppercase)[(a/b**i)%b]
for i in xrange(int(math.log(a, b)), -1, -1)]
)
num = 1412823931503067241
test = int2base(num, 36)
test2 = int(test, 36)
print test2 == num
Я сравнил пример кодировщиков, представленных в ответах на этот вопрос. На моем ноутбуке Ubuntu 18.10, Python 3.7, Jupyter, %%timeit
магическая команда и целое число 4242424242424242
В качестве входных данных я получил эти результаты:
- Пример кода Википедии: 4,87 мкс ± 300 нс на цикл (среднее ± стандартное отклонение из 7 циклов, по 100000 циклов в каждом)
- @ Mistero-х
base36encode()
: 3,62 мкс ± 44,2 нс на петлю - @user1036542-х
int2base
: 10 мкс ± 400 нс на цикл (после определения совместимости с py37) - @ mbarkhau-х
int_to_base36()
: 3,83 мкс ± 28,8 нс на цикл
Все сроки были средними ± стандартными. девиация из 7 прогонов, 100000 петель каждый.
Если вы чувствуете себя работоспособным
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
Это работает, если вы заботитесь только о положительных целых числах.
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
Вы можете определить базу с помощью int
In [1]: int('BO', base=36) == 420
Out[1]: True