PHP 随机数 C扩展随机数

由于要用到固定长度的随机字符串。

首先是一段PHP代码

1        $str_md5=md5(uniqid()); 2 $rand = mt_rand(1, 28); 3 $str1=substr($str_md5,$rand,6); 4 $rand = mt_rand(1, 28); 5 $str2=substr($str_md5,$rand,6); 6 $rand = mt_rand(1, 28); 7 $str3=substr($str_md5,$rand,6); 8 $code=substr($str1.$str2.$str3,0,8);

生成180000个随机字符串,图中是按照重复数量倒序排列,可以看到基本都有重复的。不过也是比较理想的。

由于想提升一下自己的C语言能力,所以用C重新写了一下随机生成字符串。

其中用到了随机数函数srand(),rand();

不过折腾一两个小时,随机数还是有问题。并发访问时时间可能几乎为同时,那么srand给的种子时间可以视为相同的。这样就导致了,产生的随机数也是一样的。从而产生的随机字符串也是一样的。循环输出随机字符串,几乎都是一模一样的。

后来想到了ukey,这个扩展可以实现唯一的ID,那么访问都产生唯一的ID,是不是可以将这个ID作为种子时间。答案是肯定的。

上图是产生的随机字符串,可以自定义长度。也同样可以输出只有数字的字符串。相较PHP所产生的随机字符串重复率更低且速度更快。

1 PHP_FUNCTION(get_random__num_str) 2{ 3     int length=8; 4   5     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE)  6     { 7 length=8; 8 9     } 10  length++; 11    int flag, i;   12    char* string;   13 __uint64_t timestamp = realtime(); 14    __uint64_t retval; 15    int len; 16    char buf[128]; 17 18    if (timestamp == 0ULL) { 19        RETURN_FALSE; 20    } 21 22    spin_lock(lock, pid); 23 24    if (context->last_timestamp == timestamp) { 25        context->sequence = (context->sequence + 1) & context->sequence_mask; 26        if (context->sequence == 0) { 27            timestamp = skip_next_millis(); 28        } 29 30    } else { 31        context->sequence = 0; /* Back to zero */ 32    } 33 34    context->last_timestamp = timestamp; 35 36    retval = ((timestamp - context->twepoch) << context->timestamp_left_shift) 37           | (context->datacenter_id << context->datacenter_id_shift) 38           | (worker_id << context->worker_id_shift) 39           | context->sequence; 40 41    spin_unlock(lock, pid); 42 //printf('%ld',retval); 43 srand((unsigned)retval); 44    //srand((unsigned) time(NULL ));   45    if ((string = (char*) emalloc(length)) == NULL )   46    {   47        //myLog("Malloc failed!flag:14\n");   48        RETURN_NULL() ;   49    }   50   51    for (= 0; i < length - 1; i++)   52    {   53        flag = rand() % 3;   54 55 switch (flag)   56 {   57 case 0:   58 string[i] = '1' + rand() % 5;   59 break;   60 case 1:   61 string[i] = '2' + rand() % 7;   62 break;   63 case 2:   64 string[i] = '0' + rand() % 10;   65 break;   66 default:   67 string[i] = '9';   68 break;   69 }  70 71 72          73    }   74    string[length - 1] = '\0';   75    RETURN_STRINGL(string,length,0); 76} 77 PHP_FUNCTION(get_random_str) 78{ 79     int length=8; 80   81     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE)  82     { 83 length=8; 84 85     } 86  length++; 87    int flag, i;   88    char* string;   89 __uint64_t timestamp = realtime(); 90    __uint64_t retval; 91    int len; 92    char buf[128]; 93 94    if (timestamp == 0ULL) { 95        RETURN_FALSE; 96    } 97 98    spin_lock(lock, pid); 99 100    if (context->last_timestamp == timestamp) { 101        context->sequence = (context->sequence + 1) & context->sequence_mask; 102        if (context->sequence == 0) { 103            timestamp = skip_next_millis(); 104        } 105 106    } else { 107        context->sequence = 0; /* Back to zero */ 108    } 109 110    context->last_timestamp = timestamp; 111 112    retval = ((timestamp - context->twepoch) << context->timestamp_left_shift) 113           | (context->datacenter_id << context->datacenter_id_shift) 114           | (worker_id << context->worker_id_shift) 115           | context->sequence; 116 117    spin_unlock(lock, pid); 118 //printf('%ld',retval); 119 srand((unsigned)retval); 120    //srand((unsigned) time(NULL ));   121    if ((string = (char*) emalloc(length)) == NULL )   122    {   123        //myLog("Malloc failed!flag:14\n");   124        RETURN_NULL() ;   125    }   126   127    for (= 0; i < length - 1; i++)   128    {   129        flag = rand() % 3;   130 131 switch (flag)   132 {   133 case 0:   134 string[i] = 'A' + rand() % 26;   135 break;   136 case 1:   137 string[i] = 'a' + rand() % 26;   138 break;   139 case 2:   140 string[i] = '0' + rand() % 10;   141 break;   142 default:   143 string[i] = 'x';   144 break;   145 }  146 147 148          149    }   150    string[length - 1] = '\0';   151    RETURN_STRINGL(string,length,0); 152}

上图是PHP生成18W随机字符串所用的时间

上图是C扩展生成18W随机字符串所用的时间

所用的服务器都是1G内存 双核的阿里云服务器。

只要在ukey中加入上如代码就可以生产随机字符串和随机长度数字字符串

ukey的地址http://www.oschina.net/p/ukey

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

分布式id如何生成

1.UUID生成通过网卡、时间、随机数来保证生成的唯一的字符串。优点:(1)本地生成,生成简单(2)速度快(3)高可用;缺点:(1)无序,如果存入mysq,影响B的操作性能,因为B树是需要排序的;(2)占用空间较大(36个

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Discuz X3.2源码解析 discuz_application类(转自百度)

1.discuz\_application在/source/class/discuz/discuz\_application.php中。!DiscuzX3.2源码解析discuz_application类(https://oscimg.oschina.net/oscnet/99b35d79caf70b7c74ad0838d6