• 代码收藏系列--php--生成简短唯一订单号(转载)


    代码收藏系列--php--生成简短唯一订单号

    复制代码
    /**
     * 生成商家交易单号
     * <br />特点:不重复
     * <br />示例:
     * <br />普通付款:array('shop_id'=>1,'product_id'=>array(1,2,3), 'user_id'=>1, 'ip'=>'127.0.0.1', 'amount'=>0.01, 'timestamp'=>'2017-06-22 18:02:33', 'sign_key'=>'signkey!@#123_') 结果为: ib1bd7s9bc50c787114b195e7
     * <br />合并付款:generate_trade_no(array('shop_id'=>1,'product_id'=>array(1,2,3), 'user_id'=>1, 'ip'=>'127.0.0.1', 'amount'=>0.01, 'timestamp'=>'2017-06-22 18:02:33', 'sign_key'=>'signkey!@#123_')) 结果为:ib1bd7rs5c50c787114b195e7
     * @param array $data 
     * @return string 返回30或25位位字符串,格式为: 时间{年月日时分秒,14位}+md5{16位}=30位, 例如: 20170622180940c50c787114b195e7 或 ib1bd7s9bc50c787114b195e7
     */
    function generate_trade_no(array $data, $ziptime = true) {
        ksort($data); // 根据数组的键值对数组重新排序    
        $hashtext = md5(json_encode($data)); // 把数组格式化为JSON字符串并生成MD5签名
        $time = date('YmdHis');
        if ($ziptime) {
            $time = base_convert($time, 10, 32); // 使用32进制将14位时间戳压缩到9位32进制值
        }
        $trade_no = $time . substr($hashtext, 8, 16); // 把MD5签名截取16位, 并在签名加上14位或9位日期时间戳, 组成30位或25位字符串
        return $trade_no;
    }
    
    /**
     * php生成32进制8位字符,减轻数据库唯一字段
     * <br />背景:
     * <br />一般在数据库里唯一字段我们用AUTO_ID或者CRC32或者MD5
     * <br />AUTO_ID    10进制根据数据列长度,一般是初学者用,应为在高级应用里不灵活
     * <br />CRC32 16进制8位,很直观,但是重复几率要比 MD5高,
     * <br />MD5   16进制32位,不直观,太占数据库唯一字段,数据选择压力大。
     * <br />最近2天一直在研究如何PHP做一个既有MD5的唯一能力又减少位数用在数据库开发里
     * <br />想到压缩MD5为32进制8位,下面是函数,希望大家测试或者给点意见,或者有更灵活的方法
     * <br />see: http://www.myexception.cn/database/832012.html
     * <br />示例:only('a') 结果是: H1N29LQ1
     * @param string $instr
     * @return string 返回8位字符串
     */
    function only($instr) {
        $instr = md5($instr, true);
        $dict = '0123456789ABCDEFGHIJKLMNOPQRSTUV';
        $outstr = '';
        for ($i = 0; $i < 8; $i++) {
            $ord = ord($instr[$i]);
            $outstr .= $dict[( $ord ^ ord($instr[$i + 8]) ) - $ord & 0x1F];
        }
        return $outstr;
    }
    
    /**
     * 把12位时间数值压缩成8-9位字母+数字组合字符串
     * <br />重点是加上用户编号后将永不重复!
     * <br />用途:订单号、交易号、唯一号
     * <br />如:
     * <br />timeserialize(date('y-m-d-H-i-s')), 结果是:RGXO3128
     * <br />timeserialize('17-12-31-23-59-59'), 结果是:RM31X5959
     * <br />timeserialize('50-12-31-23-59-59'), 结果是:2M31X5959
     * <br />timeserialize('0-0-0-0-0-0'), 结果是:AAAAAA
     * <br />timeserialize('99-99-99-99-99-99'), 结果是:99999999999999
     * @return string 返回8-9位字母+数字组合字符串
     * @since VER:1.0; DATE:2016-1-21; AUTHOR:SoChishun; EMAIL:14507247@qq.com; DESC:Added.
     */
    function timeserialize($time = '') {
        if (!$time) {
            $time = date('y-m-d-H-i-s');
        }
        echo '<div>', $time, '</div>';
        $atime = explode('-', $time);
        $outstr = '';
        // ASCII表:48(0)-57(9), 65(A)-90(Z), 97(a)-122(z)
        // 有效压缩范围:0-25, 48-57
        foreach ($atime as $stime) {
            $itime = $stime * 1;
            echo $itime, ',';
            // 如果数值小于26,则转换成ASCII表的字母,这样可以把两位的数值变成一位字母
            if ($itime < 26) {
                // 65(A)-90(Z)
                $outstr .= chr(65 + $itime);
                continue;
            }
            // 48(0)-57(9)
            // 如果数值在48-57之间,则转换成ASCII表的数字,把两位数转变为1数字
            if ($itime >= 48 && $itime <= 57) {
                $outstr .= chr($stime);
                continue;
            }
            $outstr .= $stime;
        }
        return $outstr;
    }
    复制代码

    版权声明:本文采用署名-非商业性使用-相同方式共享(CC BY-NC-SA 3.0 CN)国际许可协议进行许可,转载请注明作者及出处。
    本文标题:代码收藏系列--php技巧--生成简短唯一订单号
    本文链接:http://www.cnblogs.com/sochishun/p/7070365.html
    本文作者:SoChishun (邮箱:14507247#qq.com | 博客:http://www.cnblogs.com/sochishun/)
    发表日期:2017年6月23日

  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/hao987/p/8593805.html
Copyright © 2020-2023  润新知