База 62 преобразования
Как бы вы преобразовали целое число в основание 62 (как шестнадцатеричное, но с этими цифрами: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ').
Я пытался найти хорошую библиотеку Python для него, но все они, кажется, заняты преобразованием строк. Модуль Python base64 принимает только строки и превращает одну цифру в четыре символа. Я искал что-то похожее на то, что используют сокращения URL.
24 ответа
Для этого нет стандартного модуля, но я написал свои собственные функции для достижения этой цели.
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode(num, alphabet=BASE62):
"""Encode a positive number in Base X
Arguments:
- `num`: The number to encode
- `alphabet`: The alphabet to use for encoding
"""
if num == 0:
return alphabet[0]
arr = []
base = len(alphabet)
while num:
num, rem = divmod(num, base)
arr.append(alphabet[rem])
arr.reverse()
return ''.join(arr)
def decode(string, alphabet=BASE62):
"""Decode a Base X encoded string into the number
Arguments:
- `string`: The encoded string
- `alphabet`: The alphabet to use for encoding
"""
base = len(alphabet)
strlen = len(string)
num = 0
idx = 0
for char in string:
power = (strlen - (idx + 1))
num += alphabet.index(char) * (base ** power)
idx += 1
return num
Обратите внимание на тот факт, что вы можете указать любой алфавит для кодирования и декодирования. Если вы оставите alphabet
В качестве аргумента, вы получите 62-символьный алфавит, определенный в первой строке кода, и, следовательно, кодирование / декодирование в / из базы 62.
Надеюсь это поможет.
PS - для сокращения URL я обнаружил, что лучше оставить несколько запутанных символов, таких как 0Ol1oI и т. Д. Таким образом, я использую этот алфавит для своих нужд сокращения URL - "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
Повеселись.
Однажды я написал сценарий для этого, я думаю, это довольно элегантно:)
import string
BASE_LIST = string.digits + string.letters + '_@'
BASE_DICT = dict((c, i) for i, c in enumerate(BASE_LIST))
def base_decode(string, reverse_base=BASE_DICT):
length = len(reverse_base)
ret = 0
for i, c in enumerate(string[::-1]):
ret += (length ** i) * reverse_base[c]
return ret
def base_encode(integer, base=BASE_LIST):
if integer == 0:
return base[0]
length = len(base)
ret = ''
while integer != 0:
ret = base[integer % length] + ret
integer /= length
return ret
Пример использования:
for i in range(100):
print i, base_decode(base_encode(i)), base_encode(i)
Если вы ищете самую высокую эффективность (например, django), вам нужно что-то вроде следующего. Этот код представляет собой сочетание эффективных методов от Baishampayan Ghose и WoLpH и John Machin.
# Edit this list of characters as desired.
BASE_ALPH = tuple("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
BASE_DICT = dict((c, v) for v, c in enumerate(BASE_ALPH))
BASE_LEN = len(BASE_ALPH)
def base_decode(string):
num = 0
for char in string:
num = num * BASE_LEN + BASE_DICT[char]
return num
def base_encode(num):
if not num:
return BASE_ALPH[0]
encoding = ""
while num:
num, rem = divmod(num, BASE_LEN)
encoding = BASE_ALPH[rem] + encoding
return encoding
Вы можете также рассчитать свой словарь заранее. (Примечание: кодирование со строкой показывает большую эффективность, чем со списком, даже с очень длинными числами.)
>>> timeit.timeit("for i in xrange(1000000): base.base_decode(base.base_encode(i))", setup="import base", number=1)
2.3302059173583984
Закодировал и расшифровал 1 миллион чисел менее чем за 2,5 секунды. (2,2 ГГц i7-2670QM)
Следующий декодер работает с любой разумной базой, имеет более аккуратный цикл и выдает явное сообщение об ошибке, когда встречает недопустимый символ.
def base_n_decoder(alphabet):
"""Return a decoder for a base-n encoded string
Argument:
- `alphabet`: The alphabet used for encoding
"""
base = len(alphabet)
char_value = dict(((c, v) for v, c in enumerate(alphabet)))
def f(string):
num = 0
try:
for char in string:
num = num * base + char_value[char]
except KeyError:
raise ValueError('Unexpected character %r' % char)
return num
return f
if __name__ == "__main__":
func = base_n_decoder('0123456789abcdef')
for test in ('0', 'f', '2020', 'ffff', 'abqdef'):
print test
print func(test)
Если вы используете каркас django, вы можете использовать модуль django.utils.baseconv.
>>> from django.utils import baseconv
>>> baseconv.base62.encode(1234567890)
1LY7VK
В дополнение к base62, baseconv также определил base2/base16/base36/base56/base64.
Вы, вероятно, хотите base64, а не base62. Существует URL-совместимая версия, поэтому дополнительные два символа-заполнителя не должны быть проблемой.
Процесс довольно прост; рассмотрим, что base64 представляет 6 битов, а обычный байт представляет 8. Присвойте значение от 000000 до 111111 каждому из 64 выбранных символов и соедините 4 значения, чтобы они соответствовали набору из 3 base256 байтов. Повторите эти действия для каждого набора из 3 байтов, дополняя его в конце выбранным вами символом заполнения (обычно 0).
Если все, что вам нужно, это сгенерировать короткий идентификатор (так как вы упоминаете сокращения URL), а не что-то кодировать / декодировать, этот модуль может помочь:
Теперь для этого есть библиотека Python.
Я работаю над созданием пакета для этого.
Я рекомендую вам использовать мой Base.py https://github.com/kamijoutouma/bases.py который был вдохновлен Base.js
from bases import Bases
bases = Bases()
bases.toBase16(200) // => 'c8'
bases.toBase(200, 16) // => 'c8'
bases.toBase62(99999) // => 'q0T'
bases.toBase(200, 62) // => 'q0T'
bases.toAlphabet(300, 'aAbBcC') // => 'Abba'
bases.fromBase16('c8') // => 200
bases.fromBase('c8', 16) // => 200
bases.fromBase62('q0T') // => 99999
bases.fromBase('q0T', 62) // => 99999
bases.fromAlphabet('Abba', 'aAbBcC') // => 300
обратитесь к https://github.com/kamijoutouma/bases.py, чтобы узнать, какие базы можно использовать
У меня есть библиотека Python для этого именно здесь: http://www.djangosnippets.org/snippets/1431/
Самый простой.
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode_base62(num):
s = ""
while num>0:
num,r = divmod(num,62)
s = BASE62[r]+s
return s
def decode_base62(num):
x,s = 1,0
for i in range(len(num)-1,-1,-1):
s = int(BASE62.index(num[i])) *x + s
x*=62
return s
print(encode_base62(123))
print(decode_base62("1Z"))
Я надеюсь, что следующий фрагмент может помочь.
def num2sym(num, sym, join_symbol=''):
if num == 0:
return sym[0]
if num < 0 or type(num) not in (int, long):
raise ValueError('num must be positive integer')
l = len(sym) # target number base
r = []
div = num
while div != 0: # base conversion
div, mod = divmod(div, l)
r.append(sym[mod])
return join_symbol.join([x for x in reversed(r)])
Использование для вашего случая:
number = 367891
alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
print num2sym(number, alphabet) # will print '1xHJ'
Очевидно, что вы можете указать другой алфавит, состоящий из меньшего или большего количества символов, тогда он преобразует ваш номер в меньшую или большую базу чисел. Например, если указать "01" в качестве алфавита, будет выведена строка, представляющая входной номер в двоичном виде.
Вы можете перетасовать алфавит, чтобы получить уникальное представление чисел. Это может быть полезно, если вы делаете сервис сокращения URL.
Я получил большую пользу от постов других здесь. Первоначально мне понадобился код Python для проекта Django, но с тех пор я обратился к node.js, так что вот версия javascript кода (часть кодирования), которую предоставил Baishampayan Ghose.
var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
function base62_encode(n, alpha) {
var num = n || 0;
var alphabet = alpha || ALPHABET;
if (num == 0) return alphabet[0];
var arr = [];
var base = alphabet.length;
while(num) {
rem = num % base;
num = (num - rem)/base;
arr.push(alphabet.substring(rem,rem+1));
}
return arr.reverse().join('');
}
console.log(base62_encode(2390687438976, "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ"));
Вот мое решение:
def base62(a):
baseit = (lambda a=a, b=62: (not a) and '0' or
baseit(a-a%b, b*62) + '0123456789abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[a%b%61 or -1*bool(a%b)])
return baseit()
объяснение
В любой базе каждое число равно a1+a2*base**2+a3*base**3...
Таким образом, цель состоит в том, чтобы найти все a
s.
Для каждого N=1,2,3...
код изолирует aN*base**N
путем "модуляции" b
за b=base**(N+1)
который нарезает все a
больше чем N
и нарезать все a
s, так что их серийный номер меньше, чем N
уменьшением a
каждый раз функция вызывается рекурсивно текущим aN*base**N
,
Base%(base-1)==1
следовательно base**p%(base-1)==1
и поэтому q*base^p%(base-1)==q
только с одним исключением, когда q==base-1
который возвращается 0
, Чтобы исправить это дело, он возвращает 0
, Функция проверяет 0
с начала.
преимущества
В этом примере есть только одно умножение (вместо деления) и несколько операций с модулями, которые все относительно быстрые.
BASE_LIST = tuple("23456789ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz")
BASE_DICT = dict((c, v) for v, c in enumerate(BASE_LIST))
BASE_LEN = len(BASE_LIST)
def nice_decode(str):
num = 0
for char in str[::-1]:
num = num * BASE_LEN + BASE_DICT[char]
return num
def nice_encode(num):
if not num:
return BASE_LIST[0]
encoding = ""
while num:
num, rem = divmod(num, BASE_LEN)
encoding += BASE_LIST[rem]
return encoding
Вот верный и итеративный способ сделать это. Итеративный немного быстрее в зависимости от количества выполнений.
def base62_encode_r(dec):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return s[dec] if dec < 62 else base62_encode_r(dec / 62) + s[dec % 62]
print base62_encode_r(2347878234)
def base62_encode_i(dec):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
ret = ''
while dec > 0:
ret = s[dec % 62] + ret
dec /= 62
return ret
print base62_encode_i(2347878234)
def base62_decode_r(b62):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
if len(b62) == 1:
return s.index(b62)
x = base62_decode_r(b62[:-1]) * 62 + s.index(b62[-1:]) % 62
return x
print base62_decode_r("2yTsnM")
def base62_decode_i(b62):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
ret = 0
for i in xrange(len(b62)-1,-1,-1):
ret = ret + s.index(b62[i]) * (62**(len(b62)-i-1))
return ret
print base62_decode_i("2yTsnM")
if __name__ == '__main__':
import timeit
print(timeit.timeit(stmt="base62_encode_r(2347878234)", setup="from __main__ import base62_encode_r", number=100000))
print(timeit.timeit(stmt="base62_encode_i(2347878234)", setup="from __main__ import base62_encode_i", number=100000))
print(timeit.timeit(stmt="base62_decode_r('2yTsnM')", setup="from __main__ import base62_decode_r", number=100000))
print(timeit.timeit(stmt="base62_decode_i('2yTsnM')", setup="from __main__ import base62_decode_i", number=100000))
0.270266867033
0.260915645986
0.344734796766
0.311662500262
Лично мне нравится решение от Baishampayan, главным образом из-за удаления непонятных персонажей.
Для полноты и решения с лучшей производительностью в этом посте показан способ использования модуля Python base64.
Python 3.7.x
Я нашел github для некоторых алгоритмов при поиске существующего скрипта base62. В настоящее время это не сработало для текущей max-версии Python 3, поэтому я пошел дальше и исправил там, где это было необходимо, и провел небольшой рефакторинг. Я обычно не работаю с Python и всегда использовал его специально, поэтому YMMV. Вся заслуга принадлежит доктору Чжихуа Лаю. Я только что исправил недостатки этой версии Python.
файл base62.py
#modified from Dr. Zhihua Lai's original on GitHub
from math import floor
base = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
b = 62;
def toBase10(b62: str) -> int:
limit = len(b62)
res = 0
for i in range(limit):
res = b * res + base.find(b62[i])
return res
def toBase62(b10: int) -> str:
if b <= 0 or b > 62:
return 0
r = b10 % b
res = base[r];
q = floor(b10 / b)
while q:
r = q % b
q = floor(q / b)
res = base[int(r)] + res
return res
файл try_base62.py
import base62
print("Base10 ==> Base62")
for i in range(999):
print(f'{i} => {base62.toBase62(i)}')
base62_samples = ["gud", "GA", "mE", "lo", "lz", "OMFGWTFLMFAOENCODING"]
print("Base62 ==> Base10")
for i in range(len(base62_samples)):
print(f'{base62_samples[i]} => {base62.toBase10(base62_samples[i])}')
выход try_base62.py
Base10 ==> Base62
0 => 0
[...]
998 => g6
Base62 ==> Base10
gud => 63377
GA => 2640
mE => 1404
lo => 1326
lz => 1337
OMFGWTFLMFAOENCODING => 577002768656147353068189971419611424
Поскольку в репо не было информации о лицензировании, я отправил PR, чтобы оригинальный автор по крайней мере знал, что другие люди используют и изменяют свой код.
Во всех приведенных выше решениях они определяют сам алфавит, хотя на самом деле он уже доступен с использованием кодов ASCII.
def converter_base62(count) -> str:
result = ''
start = ord('0')
while count > 0:
result = chr(count % 62 + start) + result
count //= 62
return result
def decode_base62(string_to_decode: str):
result = 0
start = ord('0')
for char in string_to_decode:
result = result * 62 + (ord(char)-start)
return result
import tqdm
n = 10_000_000
for i in tqdm.tqdm(range(n)):
assert decode_base62(converter_base62(i)) == i
Я написал это некоторое время назад, и это работало довольно хорошо (негативы и все включено)
def code(number,base):
try:
int(number),int(base)
except ValueError:
raise ValueError('code(number,base): number and base must be in base10')
else:
number,base = int(number),int(base)
if base < 2:
base = 2
if base > 62:
base = 62
numbers = [0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f","g","h","i","j",
"k","l","m","n","o","p","q","r","s","t","u","v","w","x","y",
"z","A","B","C","D","E","F","G","H","I","J","K","L","M","N",
"O","P","Q","R","S","T","U","V","W","X","Y","Z"]
final = ""
loc = 0
if number < 0:
final = "-"
number = abs(number)
while base**loc <= number:
loc = loc + 1
for x in range(loc-1,-1,-1):
for y in range(base-1,-1,-1):
if y*(base**x) <= number:
final = "{}{}".format(final,numbers[y])
number = number - y*(base**x)
break
return final
def decode(number,base):
try:
int(base)
except ValueError:
raise ValueError('decode(value,base): base must be in base10')
else:
base = int(base)
number = str(number)
if base < 2:
base = 2
if base > 62:
base = 62
numbers = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f",
"g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v",
"w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L",
"M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
final = 0
if number.startswith("-"):
neg = True
number = list(number)
del(number[0])
temp = number
number = ""
for x in temp:
number = "{}{}".format(number,x)
else:
neg = False
loc = len(number)-1
number = str(number)
for x in number:
if numbers.index(x) > base:
raise ValueError('{} is out of base{} range'.format(x,str(base)))
final = final+(numbers.index(x)*(base**loc))
loc = loc - 1
if neg:
return -final
else:
return final
извините за длину всего этого
С простой рекурсией
"""
This module contains functions to transform a number to string and vice-versa
"""
BASE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
LEN_BASE = len(BASE)
def encode(num):
"""
This function encodes the given number into alpha numeric string
"""
if num < LEN_BASE:
return BASE[num]
return BASE[num % LEN_BASE] + encode(num//LEN_BASE)
def decode_recursive(string, index):
"""
recursive util function for decode
"""
if not string or index >= len(string):
return 0
return (BASE.index(string[index]) * LEN_BASE ** index) + decode_recursive(string, index + 1)
def decode(string):
"""
This function decodes given string to number
"""
return decode_recursive(string, 0)
Результаты сравнительного анализа, которые сработали для Python3 (машина: i7-8565U):
"""
us per enc()+dec() # test
(4.477935791015625, 2, '3Tx16Db2JPSS4ZdQ4dp6oW')
(6.073190927505493, 5, '3Tx16Db2JPSS4ZdQ4dp6oW')
(9.051250696182251, 9, '3Tx16Db2JPSS4ZdQ4dp6oW')
(9.864609956741333, 6, '3Tx16Db2JOOqeo6GCGscmW')
(10.868197917938232, 1, '3Tx16Db2JPSS4ZdQ4dp6oW')
(11.018349647521973, 10, '3Tx16Db2JPSS4ZdQ4dp6oW')
(12.448230504989624, 4, '03Tx16Db2JPSS4ZdQ4dp6oW')
(13.016672611236572, 7, '3Tx16Db2JPSS4ZdQ4dp6oW')
(13.212724447250366, 8, '3Tx16Db2JPSS4ZdQ4dp6oW')
(24.119479656219482, 3, '3tX16dB2jpss4zDq4DP6Ow')
"""
from time import time
half = 2 ** 127
results = []
def bench(n, enc, dec):
start = time()
for i in range(half, half + 1_000_000):
dec(enc(i))
end = time()
results.append(tuple([end - start, n, enc(half + 1234134134134314)]))
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode(num, alphabet=BASE62):
"""Encode a positive number into Base X and return the string.
Arguments:
- `num`: The number to encode
- `alphabet`: The alphabet to use for encoding
"""
if num == 0:
return alphabet[0]
arr = []
arr_append = arr.append # Extract bound-method for faster access.
_divmod = divmod # Access to locals is faster.
base = len(alphabet)
while num:
num, rem = _divmod(num, base)
arr_append(alphabet[rem])
arr.reverse()
return ''.join(arr)
def decode(string, alphabet=BASE62):
"""Decode a Base X encoded string into the number
Arguments:
- `string`: The encoded string
- `alphabet`: The alphabet to use for decoding
"""
base = len(alphabet)
strlen = len(string)
num = 0
idx = 0
for char in string:
power = (strlen - (idx + 1))
num += alphabet.index(char) * (base ** power)
idx += 1
return num
bench(1, encode, decode)
###########################################################################################################
# Remove the `_@` below for base62, now it has 64 characters
BASE_ALPH = tuple(BASE62)
BASE_LIST = BASE62
BASE_DICT = dict((c, v) for v, c in enumerate(BASE_ALPH))
###########################################################################################################
BASE_LEN = len(BASE_ALPH)
def decode(string):
num = 0
for char in string:
num = num * BASE_LEN + BASE_DICT[char]
return num
def encode(num):
if not num:
return BASE_ALPH[0]
encoding = ""
while num:
num, rem = divmod(num, BASE_LEN)
encoding = BASE_ALPH[rem] + encoding
return encoding
bench(2, encode, decode)
###########################################################################################################
from django.utils import baseconv
bench(3, baseconv.base62.encode, baseconv.base62.decode)
###########################################################################################################
def encode(a):
baseit = (lambda a=a, b=62: (not a) and '0' or
baseit(a - a % b, b * 62) + '0123456789abcdefghijklmnopqrstuvwxyz'
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[
a % b % 61 or -1 * bool(a % b)])
return baseit()
bench(4, encode, decode)
###########################################################################################################
def encode(num, sym=BASE62, join_symbol=''):
if num == 0:
return sym[0]
l = len(sym) # target number base
r = []
div = num
while div != 0: # base conversion
div, mod = divmod(div, l)
r.append(sym[mod])
return join_symbol.join([x for x in reversed(r)])
bench(5, encode, decode)
###########################################################################################################
from math import floor
base = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
b = 62;
def decode(b62: str) -> int:
limit = len(b62)
res = 0
for i in range(limit):
res = b * res + base.find(b62[i])
return res
def encode(b10: int) -> str:
if b <= 0 or b > 62:
return 0
r = b10 % b
res = base[r];
q = floor(b10 / b)
while q:
r = q % b
q = floor(q / b)
res = base[int(r)] + res
return res
bench(6, encode, decode)
###########################################################################################################
def encode(dec):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return s[dec] if dec < 62 else encode(dec // 62) + s[int(dec % 62)]
def decode(b62):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
if len(b62) == 1:
return s.index(b62)
x = decode(b62[:-1]) * 62 + s.index(b62[-1:]) % 62
return x
bench(7, encode, decode)
def encode(dec):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
ret = ''
while dec > 0:
ret = s[dec % 62] + ret
dec //= 62
return ret
def decode(b62):
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
ret = 0
for i in range(len(b62) - 1, -1, -1):
ret = ret + s.index(b62[i]) * (62 ** (len(b62) - i - 1))
return ret
bench(8, encode, decode)
###########################################################################################################
def encode(num):
s = ""
while num > 0:
num, r = divmod(num, 62)
s = BASE62[r] + s
return s
def decode(num):
x, s = 1, 0
for i in range(len(num) - 1, -1, -1):
s = int(BASE62.index(num[i])) * x + s
x *= 62
return s
bench(9, encode, decode)
###########################################################################################################
def encode(number: int, alphabet=BASE62, padding: int = 22) -> str:
l = len(alphabet)
res = []
while number > 0:
number, rem = divmod(number, l)
res.append(alphabet[rem])
if number == 0:
break
return "".join(res)[::-1] # .rjust(padding, "0")
def decode(digits: str, lookup=BASE_DICT) -> int:
res = 0
last = len(digits) - 1
base = len(lookup)
for i, d in enumerate(digits):
res += lookup[d] * pow(base, last - i)
return res
bench(10, encode, decode)
###########################################################################################################
for row in sorted(results):
print(row)
Исходная версия javascript:
var hash = "", alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", alphabetLength =
alphabet.length;
do {
hash = alphabet[input % alphabetLength] + hash;
input = parseInt(input / alphabetLength, 10);
} while (input);
Источник: https://hashids.org/
питон:
def to_base62(number):
alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
alphabetLength = len(alphabet)
result = ""
while True:
result = alphabet[number % alphabetLength] + result
number = int(number / alphabetLength)
if number == 0:
break
return result
print to_base62(59*(62**2) + 60*(62) + 61)
# result: XYZ
Извините, я не могу помочь вам с библиотекой здесь. Я бы предпочел использовать base64 и просто добавлять дополнительные символы на ваш выбор - если это возможно!
Тогда вы можете использовать модуль base64.
Если это действительно, действительно невозможно:
Вы можете сделать это самостоятельно таким образом (это псевдокод):
base62vals = []
myBase = 62
while num > 0:
reminder = num % myBase
num = num / myBase
base62vals.insert(0, reminder)