我有两个表:category(cat_id type int,cat_name)
和books(book_id type int,cat_id)
。当我为用户分配一本书时,他会得到book code
。我想形成包含12个字母数字字符的本书代码,它必须来自cat_id
和book_id
。此外,我应该能够解码代码以获取cat_id
和book_id
。有什么想法?。
答案 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个键组成;反向构造将忽略随机位的(固定)位置。