如何在PHP中生成短而独特的ID?

3
为了生成唯一的ID,我认为我必须使用PHP中的uniqid函数。
但是默认情况下,uniqid生成一个13位长的十六进制数字。
4f66835b507db

我希望将这个数字缩短为7位数,但是我想保持其唯一性。这是否可能?
4974012  

这个数字将作为用户ID使用。认证将使用此ID和密码进行。

有些人说uniqid不是唯一的!这是一个糟糕的选择吗?


你的应用程序中如何定义“unique”?只是为了获得一个不像“1,2,3,4”这样的ID吗? - Jakub
1
如果你在数据库中存储用户信息,那为什么不让数据库直接处理呢? - Tamer Shlash
如果您的脚本每个用户只启动一次,则会失去唯一性... - Vivien
@jakub:unique = 不重复,不容易猜测 - Bertaud
独特而简短! - kta
6个回答

5
任何“唯一”的数字在生成足够多的记录后最终都会发生冲突。为了确保唯一性,您需要将生成的值存储到数据库中,并在生成下一个值时检查是否存在冲突。
然而,在实践中,应用程序通常将ID生成为简单的序列1,2,3,…这样你就知道在用完数据类型之前不会发生冲突(UINT通常是32位长,可以给您提供40亿个唯一ID)。

4

Uniqid并不能保证其完整长度的唯一性,即使是完整的长度也有可能出现重复。

此外,uniqid只能在本地保持唯一性。这意味着,如果您在两个或多个服务器上同时创建用户,则可能会为两个不同的用户生成相同的ID,即使您使用的是完整长度的uniqid。

我的建议:

  • 如果您真的需要在多个具有单独数据库的服务器上运行应用程序并寻找全局唯一标识符,则应使用UUIDs。它们比uniqid返回的字符串更长,但实际上几乎不可能发生冲突。

  • 如果您仅需要本地唯一标识符,请在数据库中使用AUTO_INCREMENT。这比检查随机生成的短ID是否已经存在于数据库中要快(一点)和安全(一点)。

编辑:在下面的评论中,我们发现您不仅需要一个用户ID,而且还需要提供一个随机登录名...这很奇怪,但没关系。在这种情况下,您可以尝试在循环中使用rand,直到您获得一个不存在于数据库中的值为止。

伪代码:

$min = 1;
do {
    $username = "user" . rand($min, $min * 10);
    $min = $min * 10;
} while (user_exists($username));
// Create your user here.

自动递增提供了一个“易于知道”的数字:不危险吗? - Bertaud
那么只需要ID和密码吗? - Bertaud
1
通常情况下,用户不会使用人工数字ID进行登录,这被认为是一种糟糕的用户体验。用户可以在注册时选择自己的用户名或更好的方法是使用他们的电子邮件地址进行登录。登录/用户名字段虽然也是唯一的,但通常与ID无关。它们具有不同的功能。 - wrygiel
自增值会透露两件事情:1)使用用户ID 100,可以假设不存在太多的用户;2)使用用户ID 12345,可以假设另一个ID为12344的用户也存在。这可能是一个问题,但通常没有必要向用户显示ID。 - martinstoeckli
很不幸,我的应用程序无法处理该电子邮件(因为不必要)。当我登录我的银行帐户时,我正在使用一个ID(开心或不开心,我没有选择)。 - Bertaud
显示剩余5条评论

1

好的,通过将其缩短为7个数字并仅使用数字,您大大降低了“唯一性”。

我建议使用用户ID的自动增量,并从1000000开始,如果必须为7位数字。

如果您真的必须在没有自动增量的情况下生成它,可以使用mt_rand()生成一个7位数字的随机数:

$random = mt_rand(1000000, 9999999);

这并不理想,因为您需要检查该数字是否已被其他用户使用。


你应该使用str_pad(mt_rand(0, 9999999), 7, 0);代替。这样可以生成更多的随机数。 - Tehnix
@Chrules,你是对的,但自动增量仍然通常比str_pad的附加数字更好。另外请记住,0000001不是我个人认为的好用户ID,在某些情况下例如(int)$userId中将被截断为1 - MrCode
除非他将其存储为字符串,但无论如何,不反对自动递增,这将是更自然的方法。 - Tehnix

1

1
编写一个 while 循环,生成所需长度的随机字母和数字,循环直到创建一个尚未使用的 ID。

0

如果您正在使用数据库,请定义一个id列作为uniqueauto-incremented,然后让数据库管理您的 IDs。

这样更安全。

了解更多:mysql-doc


因此,如果您想要一个难以猜测的、@mitchsatchwell 的解决方案看起来不错。 - Vivien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接