# 对于任意一个 0~999999 之间的数字 num ,通过 func 转换得到一个 result
result = func(num)
# result 是由大写字母和数字 0-9 组成的字符串,长度固定为 8
# 如:func(1) = "A6FU1Y5F", func(2) = "YFS98TT2"
# 需要
# 1. 确保不同的输入 num 对应不同的输出 result ,
# 2. 要不容易通过已知的几个(num, result)映射找出规律,
# 3. 要能通过 result 逆向找回 num ,
# 4. 不能用写死的 dict 去做映射
我开始想的是,把数字前面补 0 ,补成 8 位 00000000~00999999
再做一个两位数字 00~99 对应两位字符串的一一映射{"00": "0A", "01": "0B", …}
然后每两位去拼出 result ,但是这样就很容易被找到规律,而且要写死一个很长的 dict ,很不优雅
不知道大佬们有没有什么好的思路?
1
ChoateYao 2022-05-24 16:16:51 +08:00 1
这不就是 36 进制嘛
|
2
sujin190 2022-05-24 16:24:07 +08:00 1
字母数字转化为 charCode 之后就是连续的数字了,查一下 base64 的编码算法照着写一个 base36 就是了呗
|
3
liuidetmks 2022-05-24 16:27:35 +08:00 1
@sujin190 base36 可麻烦多了,做 base32 会简单很多,正好去掉一些容易混淆的. l1 0O
|
4
xaplux 2022-05-24 16:28:07 +08:00
找一个基准时间戳,36 进制(基准时间戳 + 数字)
|
5
xaplux 2022-05-24 16:29:00 +08:00 1
防止找规律的话,可以再加盐
|
6
zhengjian 2022-05-24 16:30:36 +08:00 1
|
7
learningman 2022-05-24 16:32:39 +08:00 1
"要不容易通过已知的几个(num, result)映射找出规律"
又想可逆又想不被破解,哪有那么好的事。B 站那个 AV BV 的转换都能被直接看出来怎么转换的 |
8
zhengjian 2022-05-24 16:36:33 +08:00 1
reply #8
``` # https://github.com/davidaurelio/hashids-python from hashids import Hashids hashids = Hashids(slat="blablablabla", min_length=8) hashid = hashids.encode(1) number = hashids.decode(hashid) ``` |
10
darkengine 2022-05-24 17:02:22 +08:00
从高位开始
第一位 0-9 从[0-9, A-Z] 随机挑选 10 个字符作为映射。 第二位 0-9 从[0-9, A-Z] 随机挑选 10 个字符作为映射。 第二位 0-9 从[0-9, A-Z] 随机挑选 10 个字符作为映射。 …… 以此类推,最后两位可以把前面几位相加,得到的两位数再处理。要是嫌记每位 10 个字符的映射太麻烦,用 ASCII 码每位取不同的 offset 去映射也可以。 |