Base 62 转换
- 2025-02-25 09:08:00
- admin 原创
- 20
问题描述:
如何将整数转换为基数 62(类似十六进制,但具有以下数字:)0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
?
我一直在尝试寻找一个好的 Python 库,但它们似乎都忙于转换字符串。Python base64 模块只接受字符串并将单个数字转换为四个字符。我正在寻找类似于 URL 缩短器使用的东西。
解决方案 1:
这个没有标准模块,但是我编写了自己的函数来实现。
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode(num, alphabet):
"""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
请注意,您可以为其指定任何字母表来进行编码和解码。如果您省略该alphabet
参数,您将获得第一行代码中定义的 62 个字符字母表,因此将以 62 个基数进行编码/解码。
PS - 对于 URL 缩短器,我发现最好省略一些容易混淆的字符,如 0Ol1oI 等。因此,我使用这个字母表来满足我的 URL 缩短需求 -"23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
解决方案 2:
我曾经编写过一个脚本来执行此操作,我认为它非常优雅:)
import string
# Remove the `_@` below for base62, now it has 64 characters
# For Python 2 use `string.letters` instead of `string.ascii_letters
BASE_LIST = string.digits + string.ascii_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
# For Python 2 use /= instead of //=:
# integer /= length
integer //= length
return ret
使用示例:
for i in range(100):
print(i, base_decode(base_encode(i)), base_encode(i))
解决方案 3:
如果您追求最高效率(如 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
在 2.5 秒内编码和解码 100 万个数字。(2.2Ghz i7-2670QM)
解决方案 4:
如果您使用django框架,则可以使用django.utils.baseconv模块。
>>> from django.utils import baseconv
>>> baseconv.base62.encode(1234567890)
1LY7VK
除了base62,baseconv还定义了base2/base16/base36/base56/base64。
解决方案 5:
以下解码器生成器可以使用任何合理的基础,具有更整洁的循环,并在遇到无效字符时给出明确的错误消息。
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)
解决方案 6:
如果您需要的只是生成一个短 ID(因为您提到了 URL 缩短器)而不是编码/解码某些内容,那么这个模块可能会有所帮助:
https://github.com/stochastic-technologies/shortuuid/
解决方案 7:
您可能需要 base64,而不是 base62。目前有一个与 URL 兼容的版本,因此额外的两个填充字符应该不是问题。
这个过程相当简单;假设 base64 代表 6 位,而常规字节代表 8 位。为所选的 64 个字符中的每一个分配一个从 000000 到 111111 的值,并将这 4 个值放在一起以匹配一组 3 个 base256 字节。对每组 3 个字节重复此操作,在末尾使用您选择的填充字符进行填充(通常 0 很有用)。
解决方案 8:
现在有一个用于此的 python 库。
我正在为此制作一个 pip 包。
我建议你使用我的 bases.py https://github.com/kamijoutouma/bases.py,它受到 bases.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#known-basesalphabets
了解可用的基础
解决方案 9:
你可以从pypi下载 zbase62 模块
例如
>>> import zbase62
>>> zbase62.b2a("abcd")
'1mZPsa'
解决方案 10:
我从这里其他人的帖子中受益匪浅。我最初需要 Python 代码来开发 Django 项目,但从那时起我就转向了 Node.js,所以这里有Baishampayan Ghose 提供的JavaScript 版本的代码(编码部分)。
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"));
解决方案 11:
我希望以下代码片段能够有所帮助。
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 缩短服务,这会很有帮助。
解决方案 12:
史上最简单的。
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"))
解决方案 13:
Python 没有内置解决方案。所选的解决方案可能是最易读的,但我们可能会牺牲一点性能。
from string import digits, ascii_lowercase, ascii_uppercase
base_chars = digits + ascii_lowercase + ascii_uppercase
def base_it(number, base=62):
def iterate(moving_number=number, moving_base=base):
if not moving_number:
return ''
return iterate(moving_number // moving_base, moving_base * base) + base_chars[moving_number % base]
return iterate() or base_chars[0]
解释
在任何基数中,每个数字都等于, a1 + a2*base**2 + a3*base**3...
所以目标是找到所有的a
s。
对于每一个,N=1,2,3...
代码aN*base**N
通过对 进行“模”来隔离 ,其中base
对base = base**(N+1)
所有number
大于 的 进行切片N
,并对所有 进行切片,number
使得它们的序列小于 ,每次通过当前 递归调用该函数时N
都会减少。a
`aNbase*N`
优点与讨论
在这个示例中,只有一次乘法(而不是除法)和一些模数运算,这些运算都相对较快。
但是,如果您确实想要性能,那么最好使用 CPython 库。
解决方案 14:
我个人很喜欢 Baishampayan 的解决方案,主要是因为它去掉了令人困惑的字符。
为了完整性和具有更好性能的解决方案,这篇文章展示了一种使用 Python base64 模块的方法。
解决方案 15:
这是我之前写的,效果很好(包括缺点和缺点)
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
抱歉,内容太长了
解决方案 16:
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
解决方案 17:
这里有一个递归和迭代的方法。迭代方法速度稍快,具体取决于执行次数。
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
解决方案 18:
Python3.7.x
在寻找现有的 base62 脚本时,我找到了一个博士的 github,里面有一些算法。它目前不适用于当前最大版本的 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
由于 repo 中没有许可信息,我确实提交了PR,因此原作者至少知道其他人正在使用和修改他们的代码。
解决方案 19:
抱歉,我无法在这里为您提供库帮助。我更愿意使用 base64,并根据您的选择添加额外的字符 - 如果可能的话!
然后您就可以使用base64模块了。
如果这确实不可能:
您可以按照以下方式自行完成(这是伪代码):
base62vals = []
myBase = 62
while num > 0:
reminder = num % myBase
num = num / myBase
base62vals.insert(0, reminder)
解决方案 20:
使用简单的递归
"""
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)
解决方案 21:
适用于 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)
解决方案 22:
原始 JavaScript 版本:
var hash = "", alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", alphabetLength =
alphabet.length;
do {
hash = alphabet[input % alphabetLength] + hash;
input = parseInt(input / alphabetLength, 10);
} while (input);
Python:
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
解决方案 23:
在上述所有解决方案中,他们都定义了字母表本身,但实际上使用 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