基于php实现多进制转换与唯一码生成的探索

栏目: PHP · 发布时间: 6年前

内容简介:基于php实现多进制转换与唯一码生成的探索

最近要做一个兑换码生成的功能,之前有做过32位唯一码生成器,但是在业务需求中,32位的兑换码有些过长了,用户在应用内填写的时候会比较麻烦,不是很友好,倒是可以做成二维码的形式扫一下就行了,但是业务中还是存在输入兑换码的行为,所以本篇主要是关于以尽量短的字符来生成唯一码,同时要保证唯一性以及生成机制复用性(也就是利用这套机制可以生成不同种类的兑换码)的探索

以下示例代码均基于 TPRCMS 编写

探索一: 进制转换

生成的32位唯一码是16进制的一串字符,我就在想是不是可以通过提高进制来缩短字符串长度,所以有了如下的代码

代码地址: 多进制转换器ConvertLogic

其中关于10进制与62进制互转的部分,参考了 《PHP 10进制与62进制互转,可用于生成短网址》

实例代码

$uuid = "cd5fd2cfeb40aafe060f4d9597348be7";
$str = ConvertLogic::convert( $uuid, 16, 62);

输出

string(32) "cd5fd2cfeb40aafe060f4d9597348be7"
string(22) "6fxdxREtzxq6qNdSghGm7t"

经过转换后发现,长度最多压缩到21~22位,感觉还是有些长

探索二: uniqid()转62进制

uniqid()可以生成一个13位以上的16进制唯一码,将它转为62进制,会到一个更短的字符串

实验代码

$uuid = uniqid('code');
$resule = ConvertLogic::convert( $uuid, 16, 62);

//输出
//string(17) "5a5c5b182386"
//string(12) "7hoyVkRTi "

通过多次生成,从结果观察来看,有以下几个不足:

1.用这种方法生成的一批兑换码,只有后5位是变动的,前面的都不变,可能会造成结果比较好猜,容易被爆破试出来。

2.唯一性不足。在批量并发多机器生成的时候,很难保证唯一性

探索三: 伪随机生成12位字符串,用 redis 保证唯一性

示例代码

//$category_uniq是类目的hash,下面这句代码主要目的是保证同一类目下不存在相同的兑换码
RedisService::redis()->switchDB()->hSetNx('code_hash_list_'.$category_uniq,  $code, $category_uniq);
//如果同类目下已存在相同的兑换码,会返回false

伪随机字符生成代码

private static function uniq($uniq, $times)
    {
        if ($times == 0) {
            return $uniq;
        }
        $temp = substr(ConvertLogic::convert(uniqid(), 16, 62), 7);
        $uniq = $uniq . $temp;
        $times--;
        return self::uniq($uniq, $times);
    }

通过串行100万次随机生成发现,一开始差不多是4万分之一的重复率,之后会逐渐上升

探索四: redis"领票",用事务操作保证计数器的准确,一个兑换码领一个票

4位票号 + 12位伪随机码

4位票号的目的是为了保证唯一性,伪随机码是为了防止被轻易试出正确值。

这样即便知道了前面4位是票号,加一就行,但是后面12位可就难试了。

而且4位的票号可以支持一个类目有14538000个兑换码(61进制,"ZZZZ"-"1000"),即便是票号不够了,那票码长度+1即可

这个机制还有一个好处就是,可以根据情况自由修改兑换码长度

比如,只需生成几百个码,而且对安全性没有太多要求,那就可以只需要“2位票码+4位随机符”就可以了

  • 领票代码
private static function ticket($category_uniq , $baseCount){
        $key = 'code_ticket_'.$category_uniq;
        RedisService::redis()->switchDB()->watch('code_ticket_'. $category_uniq);

        $count = RedisService::redis()->switchDB()->multi()
            ->incr($key)
            ->exec();
        if($count === false){
            return self::ticket($category_uniq, $baseCount);
        }
        $ticket = $baseCount + $count;

        return $ticket;
    }

兑换码批量生成完整逻辑代码 : CodeLogic


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

见微知著-WEB用户体验解构

见微知著-WEB用户体验解构

李清 / 机械工业出版社 / 2010-4 / 36.00元

本书用解构分析的方法,系统全面地介绍了Web页面设计的相关知识和要素。 本书从整体到局部地对网站的元素进行解构,包括网站整体布局、整体配色方案,到网站各个功能区域,如登录区、内容区、广告区等,最后到按钮、反馈、验证码、字体、文字语气等多个细节元素。本书通过解构这些元素来讲述如何对用户体验设计进行优化,如何进行搜索引擎优化。 本书适用于网站交互设计师、视觉设计师、产品经理、网站设计人员、......一起来看看 《见微知著-WEB用户体验解构》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具