在我的mysql数据库中,我存储了可以在我的PHP Web应用程序中显示的商品。每个商品都有自己独特的自动增量数据库ID,我不想向用户显示。但是,我需要一些公共唯一标识符。
为什么我不想显示真实身份
我想要的公共ID
我所知道的
我在想:
问题:
答案 0 :(得分:2)
假设您的公共ID是从64个字符的字母表中提取的任何6个字符的字符串(例如英文字母的26个字母,大写和小写;印度 - 阿拉伯数字系统的10个十进制数字;以及另外两个字符,例如+
和/
)。
可以用这种方式表达的可能ID的数量是64 6 ,或接近690亿。把它放在上下文中,这个星球上的每个人几乎都有10个ID;或者每年一个身份证,直到公元4191年。我想你在申请退休或更换之前不会用尽所有可能性。
那么,如何获得这样一个6个字符的字符串呢?值得注意的是,Base-64编码一个4字节的值,少了任何填充,将产生6个字符(尽管它将只产生8个 4 ×40亿个可能的值,因为最后的字符将被绘制来自64种可能性中的4种。
然后问题变成“我应该使用什么4字节值?”你提出的建议是:
“真实”ID的单一转换
MySQL INT
是4个字节。如果您的“真实身份”是INT UNSIGNED AUTO_INCREMENT
,也许您可以使用:*
SELECT TRIM(TRAILING '=' FROM TO_BASE64(LPAD(CHAR(id),4,CHAR(0))))
FROM my_table
WHERE ...;
SELECT *
FROM my_table
WHERE id = CONV(HEX(FROM_BASE64(CONCAT(?, '=='))),16,10);
但是请注意,您只需要一个可以轻松解码的id
编码:对于其他任何人来说,转换回数字并击败本练习的对象并不会太难。可以通过bitwise XOR id
针对已知秘密来缓解此类攻击,或者更好地使用单向加密哈希函数。
时间戳的转换
MySQL TIMESTAMP
也是4字节。您可以类似地使用它(只需在上述示例中应用UNIX_TIMESTAMP()
和FROM_UNIXTIME()
)。请注意,如果两个时间戳相同(到第二个),则会发生冲突:您可能会使用最后一个字符中的额外4位来处理此类冲突,尽管这只会将问题延迟到有16个记录时同一时间戳。)
生成未使用的号码列表,如下所示:Generate 6 Digit unique number
当然这是一种可能性,但确实是一张非常大的桌子。更多信息如下。
所以,回答你的问题:
最后一个选项最适合您吗?或者你可以建议任何其他常用的方法/技术。
这取决于威胁模型。由于它的简单性,我可能会使用Base {64编码id
(可能与已知秘密进行异或)。
是否可以为所有6位数字保留900 000行表格?
即使它是6位十进制数字,你也会谈论超过900,000行(事实上是100万行)。如上所示,通过使用比十进制数字更大的字母表,可以考虑更大的空间。
“OK”并不清楚你的意思。如果有一个存储空间可供使用,我不知道会出现什么问题。虽然我们谈论的是几千兆字节的存储空间,但它的价格相当便宜。
如果(理论上)我的有效报价数量超过900 000(我知道如果发生这种情况,第2点将无关紧要),我该如何处理情况?
这就是为什么允许变长是很方便的原因。目前尚不清楚为什么要反对变长。
拥有可能相同ID的更多非活动商品是否正确?例如,某些用户可能会想要参考他的旧报价。
我不会重复使用ID。
呃,是的。见上文。将字母和数字一起使用以扩展可能的组合数量会更好吗?
*请注意,在v5.6.1中添加了MySQL函数Base64函数;如果使用早期版本,您将需要安装suitable UDF,手动执行编码 - 例如。在stored function中 - 或者在应用程序的更高层进行。
答案 1 :(得分:1)
使用字母和数字可能更好,从可用性的角度来看,你可以得到更多的组合。
在大多数情况下,存储一百万左右这些并不会破坏太多。
是先生成还是按需生成这些都是一个使用问题 - 是否有1000人可能想要同时生成代码?如果是这样,请预先构建它们。存储空间是一个因素吗?如果是这样,请考虑动态生成它们。
您应该避免让2个商品代码具有相同的可能性,因此可以根据实际需要将它们连接起来,或者确保生成器函数为每次使用生成唯一的商品代码。
答案 2 :(得分:1)
嗯,你能做的最好的事情是: 1)从具有完整参数的日期生成变量(yyyy-MM-dd hh:mm:ss)并将其与用户电子邮件连接。 在md5中编码。
2)或者使用像MSID服务器中存在的guid生成器一样叫做NEWID(),这与c#GUID相同
你可以将它从0子串到你想要多少个字符
我不建议将未使用的号码列表作为表现的原因。
将它作为整数并不是那么好也会导致更容易从6个字符中的0到9生成一个数字来破解你的数据库(注入和类似的东西)。