创建一个独特且看似随机的5个字符串

时间:2013-02-21 11:09:36

标签: php mysql unique uniqueidentifier

我正在尝试创建一个简短的5或6个字符的邀请代码,该代码将在我的网站上创建“群组”时生成。组信息存储在组表中。希望加入群组的用户必须拥有邀请码 - 他们没有必要知道任何其他内容。

显然,我需要邀请代码是唯一的,我希望在没有仔细检查的情况下生成唯一的字符串,但是找出代码一直很困难。我一直在阅读几十个问题和答案。这就是我想出来的:

当将组信息(例如名称)插入到组表中时,该行自然会被赋予唯一的自动递增ID。

  

1)抓住那个id

     

2)将其添加到1234

     

3)在将团队名称从base36转换为base10之后,简单地将值放在彼此旁边。 “NewYorkYankees”是base10(3994055806027582482648)[1263399405580602758248264820130221060827])

     

4)转换为基数36

     

5)将代码插入数据库

这保证对每个群体都是独一无二的,对吧?零碰撞的机会?我这样说是因为它根本不是随机的;我从一些独特的东西开始,我保持它独特,从不引入随机数据。

我有几个问题,因为组名是可重复的,如何在创建/ INSERTion时获取行ID?这不起作用,但它就在我所在的地方:

$query = "SELECT id FROM groups WHERE gname = :gname";
...
$uid = $result + '1234';
$hex = md5(":gname NOW()" . uniqid("$uid", true));
base_convert($hex, 10, 36);
intval($str, 36);

$query = "INSERT...";

独特,简短,但不可预测,没有所有正确的部分,用户无法使用。

3 个答案:

答案 0 :(得分:2)

这里描述how to get the last inserted auto_increment value

拥有ID后,您需要使用带有密钥的AES等对称密钥加密。它保证是唯一的(因为它可以转换回原始的明文 - 称为解密)。

您可以调整块大小以获得所需的长度(以位为单位)。对于base64,长度将是4的倍数(因为8位字符以三元组编码,导致base64中有4个字符的块)。

答案 1 :(得分:2)

$query = "INSERT INTO groups (gname, gadmin) VALUES (:gname, :gadmin)";
    $query_params = array( ':gname' => $trimmed['gname']
                           ':gadmin' => $userid );

    try {
        $stmt = $db->prepare($query);
        $result = $stmt->execute($query_params);
        $gid = $db->lastInsertId();
    }
    catch(PDOException $ex) {
        die("Failed to run query: " . $ex->getMessage());
    }

    // Use this library: https://github.com/ivanakimov/hashids.php
    $hashids = new Hashids\Hashids('this is my constant salt', 5,
                'abcdefghijklmnpqrstuvwxyz0123456789');

    $hash = $hashids->encrypt($gid);

    $query = "UPDATE groups SET invite = '$hash' WHERE id = '$gid'";
    ...

有问题的图书馆处理繁重的工作。它本身并不实际哈希。它加密输入;由于我的行ID是唯一的,因此加密结果也是如此。我不需要解密“哈希”,但选项存在。我无法严格定义长度,但我可以设置最小值并有增长空间。另外,正如您所看到的,它还允许我定义“字母”。

答案 2 :(得分:0)

为什么不连接创建组的人的IP地址或用户ID,以及包含毫秒的时间,然后是生成您发布的字符串的MD5或SHA-256?那肯定是无法预测和不重复的。