Python base 36编码
如何在Python中对以36为基数的整数进行编码,然后再对其进行解码?您是否尝试过Wikipedia的示例代码Python base 36编码,python,Python,如何在Python中对以36为基数的整数进行编码,然后再对其进行解码?您是否尝试过Wikipedia的示例代码 def base36encode(number, alphabet='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'): """Converts an integer to a base36 string.""" if not isinstance(number, (int, long)): raise TypeError('
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(数字,字母表='0123456789ABCDEFGHIjklmnopqrstuvxyz'):
“”“将整数转换为base36字符串。”“”
如果不是isinstance(数字,(int,long)):
raise TypeError('数字必须是整数')
base36=“”
符号=“”
如果数字<0:
符号='-'
数字=-数字
如果0我希望我以前读过这篇文章。答案如下:
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'))
def base36encode(编号):
如果不是isinstance(数字,(int,long)):
raise TypeError('数字必须是整数')
如果数字<0:
raise VALUERROR('数字必须为正')
字母表,base36=['0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ','']
而编号:
编号,i=divmod(编号,36)
base36=字母表[i]+base36
返回base36或字母表[0]
def BASE36解码(编号):
返回整数(数字,36)
打印(base36encode(141282393153067241))
打印(base36解码('AQF8AA0006EH'))
答案很糟糕,但我只是想和大家分享一下这个想法
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
如果您只关心正整数,则此方法有效
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)
。有关任意基的转换,请参见
以下是有关的信息。您可以使用
然后
>>> import base36
>>> assert base36.dumps(19930503) == 'bv6h3'
>>> assert base36.loads('bv6h3') == 19930503
你可以用numpy来做这个
import numpy as np
num = 2017
num = np.base_repr(num, 36)
print(num) # 1K1
num = int(num, 36)
print(num) # 2017
以下是有关和的一些信息
(这个答案最初是作为对@christopher beland答案的编辑提交的,但被拒绝,取而代之的是它自己的答案。)我对这个问题的答案中提供的示例编码器进行了基准测试。在我的Ubuntu 18.10笔记本电脑上,Python 3.7、Jupyter、%%timeit
magic命令和整数4242
作为输入,我得到了以下结果:
- 维基百科的样本代码:4.87µs±300 ns/循环(平均±标准偏差为7次运行,每个循环100000次)
- @米斯特罗的
base36encode()
:3.62µs±44.2 ns/圈
- @用户1036542的
int2base
:10µs±400 ns/回路(在修复py37兼容性后)
- @姆巴乔氏
int\u to_base36()
:3.83µs±28.8 ns/圈
所有计时均为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)
要包含小写字母,请参见@Tadeck:因为在返回它之前,你必须反转base36
。@JohnY:我的错误,那是不一样的。天哪,如果他们可以在任何基中执行str->int,你会认为他们会让你在任何基中使用内置的int->str…使它更像python,添加导入string
并用string.digits+string.lowercase
替换字母值base36encode
和base36decode
之间的接口已断开,后者将失败(可能无提示)要解码使用自定义字母表编码的任何内容,编码功能允许用户指定字母表,而解码功能不允许,因此,解码函数不是编码函数的真正逆函数,因为它依赖于默认字母表。对于Python3,此解决方案将遇到错误,因为它使用Python3中不支持的类型long
。您可以简单地从上面的函数调用中删除long
类型,或者查看下面的@AndréC.Andersen解决方案。我非常喜欢这一点,但可能我只是对较短的代码有一个缺点。math.log返回一个有限精度的浮点,因此在截断小数部分之前将其四舍五入到14位。这避免了将5.9999999999999转换为5.0,例如,当a==0时.math.log()失败,并且使用它时仍然很糟糕。我试图通过使其可与示例数据一起运行,并添加更多文档资源来改进此答案。由于某种原因,该编辑被拒绝,并解释说它更适合作为自己的答案。因此,我在下面添加了我对你答案的改进版本:这是正确的答案。我不知道为什么其他人都想重新发明轮子。@MichaelScheper,因为依赖关系很难实现。请参见leftpad
。将一个简单的函数复制并粘贴到一个执行您所需操作的文件中有时比添加一个新的外部依赖项要好。@mbarkhau您可以将第三个依赖项下载到您的存储库供应商或您的私有PyPI镜像(就像Golang项目一样)。对于独立的测试覆盖率和发布计划,这可能比复制粘贴代码片段要好
import numpy as np
num = 2017
num = np.base_repr(num, 36)
print(num) # 1K1
num = int(num, 36)
print(num) # 2017
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