我正在尝试生成一个随机序列号以放置全息贴纸,以便让客户检查所购买的产品是否真实。
序: 一旦您输入并查询该代码,它将被取消,因此下次再次执行此操作时,您会收到一条消息,指出该产品可能是假的,因为代码已被使用。
考虑到我应该为每年生产不超过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);
microtime
(gettimeofday()['usec']
)简而言之:
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
通过这种方式,我有一个每年都有变化的前缀,我可以识别出该产品是什么品牌(所以我只能使用一个数据库源)而且我仍然有足够的随机数字 - 也许 - 非常独特如果我考虑我只会“提取”1,000,000
和9,999,999
中的部分数字,然后使用上面的排序将其拆分
有些问题:
random_int()
缩短3位数?请考虑我将每月生成代码而不是每天生成代码(但我认为唯一性没有大的变化)
- 考虑到PHP中的后端我想使用
mt_rand()
函数,可能是一个很好的方法吗?
更新:在@apokryfos建议之后,我阅读了有关UUID生成和类似内容的更多内容我发现使用random_int()
代替了一个很好的折衷方案。
因为我只需要数字,所以HEX哈希对我的需求没用,并且使事情变得更复杂
我会避免使用像RSA密钥等复杂的加密内容...... 我不需要那种级别的安全性和复杂性,我只需要一种方法来生成一个唯一的序列号,尽可能最独特,如果你不刮开贴纸就不容易被猜到和取消(所以数字创建应该不是A到Z,而是随机的)
答案 0 :(得分:0)
你可以每年玩11个随机数字,这样11位数字1到99999999999(999亿就超过200万)所以w.r.t.足够的组合,我认为你被覆盖。
然而,使用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);
碰撞次数通常较低(第一次碰撞发生在大约300 000 - 500 000个数字,因此非常罕见。
数组$keys
中的每个值都是一个11位数字,它是随机且唯一的。
这种方法相对较快但要注意它需要相当多的内存(超过128MB)。
这就是说,一种更常用的方法是生成universally unique identifier (UUID),它更有可能是唯一的,因此不需要检查唯一性。