Skip to content

Instantly share code, notes, and snippets.

@toddlerya
Last active January 14, 2024 18:16
Show Gist options
  • Save toddlerya/e134007fada31377659a9281e21767fc to your computer and use it in GitHub Desktop.
Save toddlerya/e134007fada31377659a9281e21767fc to your computer and use it in GitHub Desktop.
62进制与10进制转换,主要用于短URL生成解析
#!/usr/bin/env python
# encoding: utf-8
# author: toddlerya
# date: 2019/03/31
# python_version: 3.7.1
import string
import unittest
class Base62(object):
"""
基于abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789共计62个ascii字符
构建62进制编码, 实现正整型十进制数据字符编码和解码
"""
def __init__(self):
self.BASE_STR = string.ascii_letters + string.digits
self.BASE = len(self.BASE_STR)
def __10to62(self, digit, value=None):
# 小心value参数的默认传参数陷阱
# 不应写为value=[], 这将导致只有一次初始化, 每次调用列表的值都会累加
# 应该声明为None, 只有为None才进行初始化, 这样能保持每次调用都会初始化此参数
# https://pythonguidecn.readthedocs.io/zh/latest/writing/gotchas.html
if value is None:
value = list()
rem = int(digit % self.BASE)
value.append(self.BASE_STR[rem])
div = int(digit / self.BASE)
if div > 0:
value = self.__10to62(div, value)
return value
def __62to10(self, str_value):
value_list = list(str_value)
value_list.reverse()
temp_list = [self.BASE_STR.index(ele) * (self.BASE ** n) for n, ele in enumerate(value_list)]
return sum(temp_list)
def encode_10to62(self, digit: int) -> str:
"""
10进制转为62进制
"""
if not isinstance(digit, int) or digit < 0:
raise TypeError('请输入正整数')
value = self.__10to62(digit)
value.reverse()
value = ''.join(value)
return value
def decode_62to10(self, str62: str) -> int:
"""
62进制转为10进制
"""
check = sum([1 for ele in str62 if ele not in self.BASE_STR])
if check > 0 or len(str62) == 0 or not isinstance(str62, str):
raise TypeError('请输入正确的62进制数')
return self.__62to10(str62)
class TestBase62(unittest.TestCase):
def setUp(self):
self.code = Base62()
def test_encode_10to62_border(self):
self.assertEqual(first=self.code.encode_10to62(0), second='a')
self.assertEqual(first=self.code.encode_10to62(1), second='b')
self.assertEqual(first=self.code.encode_10to62(61), second='9')
self.assertEqual(first=self.code.encode_10to62(62), second='ba')
def test_encode_10to62_nornal(self):
self.assertEqual(first=self.code.encode_10to62(122262), second='FX8')
def test_decode_62to10_border(self):
self.assertEqual(first=self.code.decode_62to10('a'), second=0)
self.assertEqual(first=self.code.decode_62to10('b'), second=1)
self.assertEqual(first=self.code.decode_62to10('9'), second=61)
self.assertEqual(first=self.code.decode_62to10('ba'), second=62)
def test_decode_62to10_nornal(self):
self.assertEqual(first=self.code.decode_62to10('FX8'), second=122262)
def test_encode_10to62_datatype_error(self):
self.assertRaises(TypeError, self.code.encode_10to62, -1)
self.assertRaises(TypeError, self.code.encode_10to62, -1212)
self.assertRaises(TypeError, self.code.encode_10to62, 22.1212)
self.assertRaises(TypeError, self.code.encode_10to62, '')
self.assertRaises(TypeError, self.code.encode_10to62, 'safs#121')
def test_decode_62to10_datatype_error(self):
self.assertRaises(TypeError, self.code.decode_62to10, -1)
self.assertRaises(TypeError, self.code.decode_62to10, -1212)
self.assertRaises(TypeError, self.code.decode_62to10, 22.1212)
self.assertRaises(TypeError, self.code.decode_62to10, '')
self.assertRaises(TypeError, self.code.decode_62to10, 'safs#121')
if __name__ == "__main__":
unittest.main()
@h3h3da
Copy link

h3h3da commented Feb 9, 2023

a="aa"
b=Base32()
a==b.encode_10to62(b.decode_62to10(a))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment