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


Generate unique 12 letter alphanumeric string from two primary keys of table in php

我有两个表:category(cat_id type int,cat_name)books(book_id type int,cat_id)。当我将一本书分配给用户时,他将获得一个book code。我想形成这个包含12个字母数字字符的书码,它必须起源于cat_idbook_id。此外,我应该能够解码代码以获得cat_idbook_id。任何主意?。

有一个更简单的方法是使用HEX,但是你需要决定用多少数字来表示图书,用多少数字来表示类别。

例如,我建议用8表示书,用4表示类别,如下所示。通过使用十六进制1,最大记录是FFFFFFFF FFFF,在这里您可以用完所有的unsigned int for books (max。4294967295本书)和65535类

实际上,LPAD(HEX(book_id), 8, '0')表示前8位数字,LPAD(HEX(cat_id), 4, '0')表示后4位数字。

所以你想要的图书代码可以通过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(区分大小写)编码。这种编码需要您自己的用户程序代码。

好了…

this可以处理最大有符号整数类型。并且产生不超过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);

更新:对不起,我犯了一个错误。这应该与更新后的代码相同。

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

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

如果在图书代码字符集中再添加5个字符,将会有41^12 = 2.256e19个不同的值,这足以创建一对一的映射。

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

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