我正在尝试创建一个简短的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...";
独特,简短,但不可预测,没有所有正确的部分,用户无法使用。
答案 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?那肯定是无法预测和不重复的。