从php中的表的两个主键生成唯一的12个字母的字母数字字符串

时间:2013-04-25 09:26:17

标签: php algorithm

我有两个表:category(cat_id type int,cat_name)books(book_id type int,cat_id)。当我为用户分配一本书时,他会得到book code。我想形成包含12个字母数字字符的本书代码,它必须来自cat_idbook_id。此外,我应该能够解码代码以获取cat_idbook_id。有什么想法?。

3 个答案:

答案 0 :(得分:3)

使用HEX有一种更简单的方法,但您需要确定书籍使用的位数和类别的数量。

例如,我建议使用8用于书籍,4用于类别。 通过使用十六进制数,最大记录为FFFFFFFF FFFF,您可以使用书中的所有unsigned int(最多4294967295本书)和65535种类别。

实际上,前{8}位为LPAD(HEX(book_id), 8, '0'),后4位为LPAD(HEX(cat_id), 4, '0')

所以您想要的图书代码可以通过SELECT CONCAT(LPAD(HEX(book_id), 8, '0'),LPAD(HEX(cat_id), 4, '0')) FROM books

完成

要取回: SELECT UNHEX(substr(code,1,8)) as book_id, UNHEX(substr(code,9,4)) as cat_id FROM bookcode WHERE id=1

如果您想在书籍代码中使用更大的数据集,则可以对这两个项目尝试base36甚至base62(区分大小写)编码。这种编码需要您自己的用户程序代码。

答案 1 :(得分:2)

好的,你去......

这可以处理最大有符号整数类型。并且产生不超过12个字符。

$firstId = "2147483646";
$secondId = "2147483646";
$firstBinary  = str_pad(base_convert($firstId, 10, 2), 31, "0", STR_PAD_LEFT);
$secondBinary  = str_pad(base_convert($secondId, 10, 2), 31, "0", STR_PAD_LEFT);
$finalBase36 = str_pad(base_convert($firstBinary.$secondBinary, 2, 36), 12, "0", STR_PAD_LEFT);
var_dump($finalBase36);

更新:抱歉,我犯了一个错误..这应该用更新的代码进行操作。

答案 2 :(得分:0)

假设int类型是32位无符号整数。 2 int组合将具有2 ^ 64个唯一值,大约为1.844e19。

如果我们只使用小写或大写英文字母加上数字,则有36 ^ 12 = 4.738e18个不同的值,这不足以创建从2个键到书籍代码的一对一映射

如果您为书籍代码的字符集添加5个以上的字符,则会有41 ^ 12 = 2.256e19个不同的值,这足以创建一对一的映射。

但是,转换将涉及除法和乘法,当您从书籍代码转换回键时,可能会发生整数溢出。

如果可能,您可能希望将字符集扩展为64个字符:26 * 2大写/小写英文字母,10位数和2个特殊字符(可能是_-) ,你可以玩位移 - 这是整数溢出安全。对于未使用的位,您可能希望用随机数据填充它,这些数据由2个键组成;反向构造将忽略随机位的(固定)位置。