防伪唯一序列号生成

nnt7mjpx  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(357)

我正在尝试生成一个随机序列号来贴在全息贴纸上,以便让客户检查购买的产品是否真实。
前言:一旦你输入并查询了该代码,它将为空,所以下次你再次这样做,你会收到一条消息,该产品可能是假的,因为代码已经被使用。
考虑到我应该为一个年产量不超过2/3百万件的工厂制作这个系统,对我来说,有点难以理解如何设置所有的东西,至少第一次…
我考虑了4组20位数的代码(没有字母,因为用户必须很容易阅读和输入代码)

12345-67890-98765-43210

这是我认为最简单的方法:

function mycheckdigit()
{
...
return $myserial;
}
$mycustomcode="123";
$qty=20000;
$myfile = fopen("./thefile.txt","w")  or die("Houston we got a problem here");
//using a txt file for a test, should be a DB instead...
for($i=0;$i<=$qty;$i++) {
    $txt = date("y").$mycustomcode.str_pad(gettimeofday()['usec'],6,STR_PAD_LEFT).random_int(1000000,9999999). "\n";
    //here the code to make check digits
    mycheckdigit($txt);
    fwrite($myfile,$myserial);
}
fclose($myfile);

第一组标识类似年份:18和3自定义代码
第二组包括 microtime ( gettimeofday()['usec'] )
第三个是完全随机的
最后一组包括3个随机数和一个校验位(第1组)和一个校验位(第2组)
简而言之:

Y= year
E= part of the EAN or custom code
M= Microtime generated number (gettimeofday()['usec'])
D= random_int() digits
C= Check Digit

YYEEE-MMMMM-MDDDD-DDDCC

这样,我就有了一个每年都会改变的前缀,我可以识别出产品是什么品牌(所以我只能使用一个db源),而且我仍然有足够的随机数字,如果我考虑到我只会“提取”来自 1,000,000 以及 9,999,999 然后使用上面的排序将其拆分
一些问题:
考虑到200万个代码,你认为我有足够的组合在一年内不产生相同的代码吗?如果没有必要的话,我不会在数据库中查找相同的代码,因为这会减慢批量生成(在生产过程中批量执行)
最好放一些也唯一的标识符,比如一年中的某一天(001-365)并使 random_int() 短3位数?请考虑我将每月生成代码,而不是每天(但我认为在唯一性方面没有大的变化)
考虑到php的后端,我正在考虑使用 mt_rand() 功能,可能是个好方法?
更新:在@apokryfos建议之后,我阅读了更多关于uuid生成和类似的内容,我发现使用 random_int() 相反。因为我只需要数字,所以十六进制哈希对我的需要没有用处,使事情变得更复杂
我会避免使用复杂的加密方法,比如rsa密钥等等……我不需要那种安全性和复杂性,我只需要一种方法来生成唯一的序列号,尽可能地唯一,如果不刮标签,就不容易猜测和为空(所以数字创建不应该是a到z,而是随机的)

uhry853o

uhry853o1#

你每年可以玩11个随机数字,所以这是11个数字1到99999999999(999亿比200万多得多),所以我认为你有足够的组合。
但是使用 mt_rand 很可能会发生碰撞。以下是一种在使用数据库之前计划使用200万个随机数的方法:

<?php
$arr = [];
while (count($arr) < 1000000) {
    $num = mt_rand(1, 99999999999);
    $numStr = str_pad($num,11,0,STR_PAD_LEFT); //Force 11 digits
    if (!isset($arr[$numStr])) {
        $arr[$numStr] = true;
    } 
}
$keys= array_keys($arr);

碰撞的次数通常很低(第一次碰撞发生在大约30万到50万个数字之间,所以这是非常罕见的。
数组中的每个值 $keys 是一个11位数的随机唯一数字。
这种方法相对较快,但需要注意的是,它需要相当多的内存(超过128mb)。
这就是说,一个更普遍使用的方法是生成一个通用唯一标识符(uuid),它更可能是唯一的,因此实际上不需要检查唯一性。

相关问题