PHP随机数 C扩展随机数


Posted in PHP onMay 04, 2016

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

首先是一段PHP代码

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

PHP随机数 C扩展随机数

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

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

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

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

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

PHP随机数 C扩展随机数

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

PHP_FUNCTION(get_random__num_str)
{
  int length=8;
  
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) 
  {
  length=8;
   
  }
  length++;
 int flag, i; 
 char* string; 
 __uint64_t timestamp = realtime();
 __uint64_t retval;
 int len;
 char buf[128];
 
 if (timestamp == 0ULL) {
  RETURN_FALSE;
 }
 
 spin_lock(lock, pid);
 
 if (context->last_timestamp == timestamp) {
  context->sequence = (context->sequence + 1) & context->sequence_mask;
  if (context->sequence == 0) {
   timestamp = skip_next_millis();
  }
 
 } else {
  context->sequence = 0; /* Back to zero */
 }
 
 context->last_timestamp = timestamp;
 
 retval = ((timestamp - context->twepoch) << context->timestamp_left_shift)
   | (context->datacenter_id << context->datacenter_id_shift)
   | (worker_id << context->worker_id_shift)
   | context->sequence;
 
 spin_unlock(lock, pid);
 //printf('%ld',retval);
 srand((unsigned)retval);
 //srand((unsigned) time(NULL )); 
 if ((string = (char*) emalloc(length)) == NULL ) 
 { 
  //myLog("Malloc failed!flag:14\n"); 
  RETURN_NULL() ; 
 } 
 
 for (i = 0; i < length - 1; i++) 
 { 
  flag = rand() % 3; 
   
  switch (flag) 
  { 
   case 0: 
    string[i] = '1' + rand() % 5; 
    break; 
   case 1: 
    string[i] = '2' + rand() % 7; 
    break; 
   case 2: 
    string[i] = '0' + rand() % 10; 
    break; 
   default: 
    string[i] = '9'; 
    break; 
  } 
   
   
   
 } 
 string[length - 1] = '\0'; 
 RETURN_STRINGL(string,length,0);
}
 PHP_FUNCTION(get_random_str)
{
  int length=8;
  
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) 
  {
  length=8;
   
  }
  length++;
 int flag, i; 
 char* string; 
 __uint64_t timestamp = realtime();
 __uint64_t retval;
 int len;
 char buf[128];
 
 if (timestamp == 0ULL) {
  RETURN_FALSE;
 }
 
 spin_lock(lock, pid);
 
 if (context->last_timestamp == timestamp) {
  context->sequence = (context->sequence + 1) & context->sequence_mask;
  if (context->sequence == 0) {
   timestamp = skip_next_millis();
  }
 
 } else {
  context->sequence = 0; /* Back to zero */
 }
 
 context->last_timestamp = timestamp;
 
 retval = ((timestamp - context->twepoch) << context->timestamp_left_shift)
   | (context->datacenter_id << context->datacenter_id_shift)
   | (worker_id << context->worker_id_shift)
   | context->sequence;
 
 spin_unlock(lock, pid);
 //printf('%ld',retval);
 srand((unsigned)retval);
 //srand((unsigned) time(NULL )); 
 if ((string = (char*) emalloc(length)) == NULL ) 
 { 
  //myLog("Malloc failed!flag:14\n"); 
  RETURN_NULL() ; 
 } 
 
 for (i = 0; i < length - 1; i++) 
 { 
  flag = rand() % 3; 
   
  switch (flag) 
  { 
   case 0: 
    string[i] = 'A' + rand() % 26; 
    break; 
   case 1: 
    string[i] = 'a' + rand() % 26; 
    break; 
   case 2: 
    string[i] = '0' + rand() % 10; 
    break; 
   default: 
    string[i] = 'x'; 
    break; 
  } 
   
   
   
 } 
 string[length - 1] = '\0'; 
 RETURN_STRINGL(string,length,0);
}

PHP随机数 C扩展随机数

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

PHP随机数 C扩展随机数

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

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

只要在ukey中加入上如代码就可以生产随机字符串和随机长度数字字符串,PHP唯一ID生成扩展ukey。

php.ini的配置项:

[ukey]
ukey.datacenter = integer
ukey.worker = integer
ukey.twepoch = uint64

datacenter配置项是一个整数, 用于设置数据中心;
worker配置项是一个整数, 用于设置数据中心的机器序号;
twepoch配置项是一个64位的整数, 用于设置时间戳基数, 此值越大, 生成的ID越小;

安装:

$ cd ./ukey
$ phpize
$ ./configure
$ make
$ sudo make install

Ukey提供3个有用的函数:

ukey_next_id() -- 用于生成唯一ID
ukey_to_timestamp(ID) -- 用于将ID转换成时间戳
ukey_to_machine(ID) -- 用于将ID转换成机器信息

使用实例:

<?php
$id = ukey_next_id();
echo $id;
 
$timestamp = ukey_to_timestamp($id);
echo date('Y-m-d H:i:s', $timestamp);
 
$info = ukey_to_machine($id)
var_dump($info);
?>

以上就是本文的全部内容,希望对大家的学习有所帮助。

PHP 相关文章推荐
?生?D片??C字串
Dec 06 PHP
10条PHP编程习惯助你找工作
Sep 29 PHP
简单PHP上传图片、删除图片实现代码
May 12 PHP
PHP中usort在值相同时改变原始位置问题的解决方法
Nov 27 PHP
$_GET['goods_id']+0 的使用详解
Jun 06 PHP
解析php file_exists无效的解决办法
Jun 26 PHP
php中生成随机密码的自定义函数代码
Oct 21 PHP
PHP操作MySQL事务实例
Nov 05 PHP
php去除数组中重复数据
Nov 18 PHP
php实现的单一入口应用程序实例分析
Sep 23 PHP
PHP中如何判断exec函数执行成功?
Aug 04 PHP
php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)
Sep 23 PHP
PHP正则表达式过滤html标签属性(DEMO)
May 04 #PHP
Joomla使用Apache重写模式的方法
May 04 #PHP
Joomla开启SEF的方法
May 04 #PHP
Joomla简单判断用户是否登录的方法
May 04 #PHP
Joomla实现组件中弹出一个模式(modal)窗口的方法
May 04 #PHP
joomla组件开发入门教程
May 04 #PHP
Yii2前后台分离及migrate使用(七)
May 04 #PHP
You might like
Ha0k 0.3 PHP 网页木马修改版
2009/10/11 PHP
php json_encode奇怪问题说明
2011/09/27 PHP
php跨域cookie共享使用方法
2014/02/20 PHP
PHP中实现获取IP和地理位置类分享
2015/02/10 PHP
js去除空格的12种实用方法
2013/11/08 Javascript
Javascript实现返回上一页面并刷新的小例子
2013/12/11 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
Dojo Javascript 编程规范 规范自己的JavaScript书写
2014/10/26 Javascript
js编写贪吃蛇的小游戏
2020/08/24 Javascript
Javascript中的arguments对象
2016/06/20 Javascript
Vue.js双向绑定实现原理详解
2016/12/22 Javascript
原生JS实现跑马灯效果
2017/02/20 Javascript
JavaScript操作文件_动力节点Java学院整理
2017/06/30 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
使用jQuery实现两个div中按钮互换位置的实例代码
2017/09/21 jQuery
微信网页登录逻辑与实现方法
2019/04/29 Javascript
python魔法方法-属性访问控制详解
2016/07/25 Python
python去掉行尾的换行符方法
2017/01/04 Python
对TensorFlow的assign赋值用法详解
2018/07/30 Python
通过python将大量文件按修改时间分类的方法
2018/10/17 Python
python实现静态web服务器
2019/09/03 Python
python实现批量转换图片为黑白
2020/06/16 Python
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
中国排名第一的外贸销售网站:LightInTheBox.com(兰亭集势)
2016/10/28 全球购物
微软中国官方旗舰店:销售Surface、Xbox One、笔记本电脑、Office
2018/07/23 全球购物
英国国家美术馆商店:National Gallery
2019/05/01 全球购物
Dogeared官网:在美国手工制作的珠宝
2019/08/24 全球购物
数字天堂软件测试面试题
2012/12/23 面试题
班主任对学生的评语
2014/04/26 职场文书
2014年医院工作总结
2014/11/20 职场文书
父亲节寄语大全
2015/02/27 职场文书
2015年网管个人工作总结
2015/05/22 职场文书
2015银行年终工作总结范文
2015/05/26 职场文书
毕业设计答辩开场白
2015/05/29 职场文书
2015年暑期社会实践总结
2015/07/13 职场文书
优秀大学生申请书
2019/06/24 职场文书