2016-06-14 80 views
0

我有一个users表,我需要为每个用户创建一个唯一的,随机的字母数字“ID”(它们通常具有自动增量ID)。这个标识符必须:如何生成与给定模式匹配的随机外观唯一标识

  • 是唯一
  • 是随机寻找
  • 匹配的模式AAAA-1234(4个字母,4个数字)

有没有更好的办法,而不是不断随机生成的字符串,直到我发现一个不在数据库中的呢?

+0

当你说'随机看'你的意思是这些数字不应该是相应的? –

+0

@PavelPetrov – nXu

+0

可能是您需要的算法类似于生成信用卡号码的算法。如果你在Cryptography SE中提出这个问题,你可能会得到更好的答案。 –

回答

2

为每个用户指定一个无聊旧顺序的整数(或使用您提到的其他ID)。称它为$x

Set $x = (($x + 2135587861) * 2654435769) & 0xffffffff

设置$x = $x^($x >> 15)

再次设置$x = (($x + 2135587861) * 2654435769) & 0xffffffff

计算$x % 26并根据结果选择一个字母a-z。设置$x = $x/26。重复四次(我不知道PHP,所以你在这里得到口头指示)。

计算$x % 10并根据结果选择数字0-9。设置$x = $x/10。重复四次。

头六个结果我得到的是:

HSQG-2102 
DNQO-1176 
TEKJ-5435 
EHWX-6540 
UPPH-0450 
MVIX-5036 

这不完全完美,但它是不明显的。也许这就够了。

此外,它只适用于前40亿(ish)用户在碰撞之前,但这只是一点点的字符串格式的限制。

+0

我真的不明白这里的数字,但如果我看到正确,这基本上意味着每个$ x将映射到恰好一个字符串,这将是唯一的,直到$ x <16^8,对吧? – nXu

+1

是的,它们是独一无二的。所有的神奇数字都是任意的,我只是选择了一些看起来可行的东西。我使用了黄金比例的前64位。唯一的限制是乘数必须是奇数 - 它具有数学特性,即使在&&0xffffffff之后,每个可能的输入都映射到唯一的输出。由于所有操作都具有相同的属性,因此我们知道我们不会将任何两个输入折叠到相同的输出(碰撞)中,并且理论上我们可以反转操作以发现原始数字。 – sh1

+0

谢谢你的解释! – nXu