[python]利用uuid和base64实现资源主键id

不想用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更保险

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值