|
|
1
6
您需要一些结构上正确的东西,例如置换函数:这是一个函数,它对一个整数(顺序计数器)进行一对一的可逆映射到另一个整数。 一些例子(这些的任何组合都应该有效):
示例:此函数将转换0、1、2、3、5、。分为13、4、12、7、15……。对于最多15个数字:
编辑 一种更简单的方法是使用线性同余生成器(LCG,通常用于生成随机数),它由以下形式的公式定义:
为了 good values A、C和M的顺序是x_0、x_1。x_m-1将只包含一次0和m-1之间的所有数字。现在可以从线性递增的索引开始,并使用 下一个 在LCG序列中作为“秘密”密钥的值。 编辑2 实施: 你可以 design your own LCG parameters ,但是如果您弄错了,它将无法覆盖整个范围(因此会有重复项),因此我将在此处使用一组已发布并尝试过的参数。 this paper :
这会给你一个2*31的范围。使用pack()可以将得到的整数作为字符串,base64_encode()使其成为可读字符串(最多6个有效字符,每字节6位),因此这可能是您的函数:
|
|
|
2
1
您可能会生成当前日期时间/随机数的MD5哈希,并将其截断到所需的长度(5-8个字符),然后将其存储为ID字段。 如果您使用将这些信息存储在数据库中,则不需要使用for循环来执行冲突检查,但可以只执行select语句-类似于
其中:id是新生成的id。如果c大于0,则说明它已经存在。 编辑 这可能不是最好的方法。但我会给它一个机会,所以我猜你需要的是某种方法,把一个数字转换成一个唯一的短字符串,而不是按顺序。 我猜就像你说的,base64编码已经完成了从数字到短字符串的转换。为了避免序列问题,您可以在自动生成的ID与某个“随机”值(唯一映射)之间进行一些映射。然后您可以base64编码这个唯一的值。 您可以如下生成这个映射。具有1-10000000之间的临时表存储值。按随机顺序排序,并将其存储到映射表中。
其中,mappingtable将具有2个字段id(您的自动生成的id将对照该字段查找)和mappedid(您将为其生成base64编码)。 当您接近10000000时,您可以再次运行上述代码,并用10000001-20000000或类似的值更改临时表中的值。 |
|
|
3
1
您可以使用位异或对某些位进行加扰:
|
|
4
0
我认为这永远不会是真正安全的,因为您只需要在短的唯一字符串后面找到加密方法就可以劫持一个ID。在您的设置中,检查循环中的冲突真的有那么大的问题吗? |
|
|
5
0
完全正确。尤其是当你达到80%的碰撞概率时,一个被截断的MD5将和任何一个随机数一样好,以保证它本身的唯一性,即没有价值。 但既然您使用的是数据库,为什么不使用唯一索引呢?通过这种方式,MySQL本身就完成了唯一性检查(比使用循环更有效)。只需尝试用MD5生成的密钥进行插入,如果失败,请重试… |
|
|
6
0
如果不能使用自动递增字段,并且需要 绝对地 唯一值,使用 UUID . 如果您决定使用任何其他方法(除了自动增量),那么不检查碰撞是很愚蠢的。 |
|
|
7
0
|
|
|
8
-1
一个递增数字的MD5应该是可以的,但我担心如果您将MD5(通常是128位)截断为5-8个字符,您几乎肯定会破坏它作为唯一签名的能力… |