不想用mysql的自增id(造数据的时候会很麻烦),而且tiDB也不支持.
而且主键希望和资源的业务属性是可对应的.
比如设备就是域+ip,这样如果删除了再添加,主键不会改变.
直接用uuid3,32字节的字符串有点太长,16byte的bytes操作又麻烦, 128bit的int又超过了mysql uint64的限制(拆2字节太麻烦)
搜索了一下uuid的压缩方法,发现base64编码还是比较靠谱的.
使用base64编码可以压缩到22byte, 不过python的base64函数是需要补齐4位的.
查看文档,还有b85编码,可以进一步压到20byte,而且b85encode/b85decode是默认不填充的.
ok,就它了
import uuid
import hashlib
name = 'test_nameqqqwwe1234567890'
#namespace = uuid.NAMESPACE_URL
namespace = uuid.NAMESPACE_DNS
print(uuid.uuid1())
print(uuid.uuid3(namespace,name))
print(uuid.uuid3(namespace,name).int)
print(uuid.uuid3(namespace,name).bytes)
print(uuid.uuid3(namespace,name).hex)
print(uuid.uuid4())
print(uuid.uuid5(namespace,name))
print(hashlib.md5(name.encode(encoding='UTF-8')).hexdigest())
#测试将字符串转为uuid对象
print(uuid.UUID('7e9fc1763b19394a953083391161f8e9'))
#测试用base64来压缩uuid
import base64
print('test str base64')
def safe_base64_encode(s):
b = base64.b64encode(s.encode('utf-8'))#因为python3.x中字符都为unicode编码,而b64encode函数的参数为byte类型,所以必须先转码
#b= base64.b64encode(s)
bstr_tmp = str(b,'utf-8') #把byte类型的数据转换为utf-8的数据
print(bstr_tmp)
b_str= bstr_tmp.strip(r'=+') #用正则把 = 去掉
return b_str
def safe_base64_encodebyte(bs): #b64encode只能接收byte
#b = base64.b64encode(s.encode('utf-8'))#因为python3.x中字符都为unicode编码,而b64encode函数的参数为byte类型,所以必须先转码
b= base64.b64encode(bs)
bstr_tmp = str(b,'utf-8') #把byte类型的数据转换为utf-8的数据
print(bstr_tmp)
b_str= bstr_tmp.strip(r'=+') #用正则把 = 去掉
return b_str
def safe_base64_decode(s): #b64decode可以接收字符串或者byte
import math
padlen=math.ceil(len(s)/4)*4
print(padlen)
pstr=ten64.ljust(padlen,'=')
return pstr
s = "binarybstr\x00string"
safe_b = safe_base64_encode(s)
print (safe_b)
print("test base64")
en64=base64.b64encode(uuid.uuid3(namespace,name).bytes) #b64encode只能接收byte
#en64=base64.b64encode(uuid.uuid3(namespace,name).hex.encode('utf-8')) #b64encode只能接收byte. 这样更长了
print(en64)
#trime尾部的=
#ten64=str(en64,'utf-8').strip(r'=+')
ten64=safe_base64_encodebyte(uuid.uuid3(namespace,name).bytes)
print(ten64)
#恢复时补全尾部的=
ren64=safe_base64_decode(ten64)
#ren64=ten64.ljust(24,'=') #uuid16byte *4/3=22byte,补全为4的倍数24
d64=base64.b64decode(ren64) #b64decode可以接收字符串或者byte
print(d64)
print('test base85')
en85=base64.b85encode(uuid.uuid3(namespace,name).bytes) #20位,而且不用考虑==
print(en85)
de85=base64.b85decode(en85)
print(de85)
test base85
b'FcW&B=DR*3jUe2byo||5'
b'0\x13z\xa2\xe6\xbb>"\x8d \xdc\x9a\xbc\x8c\xc9G'
不过, b85不是urlsafe的
如果需要在浏览器里面直接用,还是用b64更保险