让知识连接你我
投稿赚钱
当前位置: 首页 > 后端开发 > PHP 随机数 C扩展随机数,运用固定长度
  • 101
  • 微信分享

    扫一扫,在手机上查看

PHP 随机数 C扩展随机数,运用固定长度

2019.09.16 10:00 244 浏览 举报

  PHP 随机数 C扩展随机数

  鉴于要运用固定长度的任意字符串。

  前提是这段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,$randa,6);
  $rand= mt_rand(1, 28);
  $str3=substr($str_md5,$rand,6);
  $code=substr($str1.$str2.$str3,0,8);

  形成180000个任意字符串,图中是根据反复数量倒序排序,能够看见基础全是反复的。但是全是较为满意的。

  鉴于想提高一下自身的C语言专业能力,因此用C重新写了一下任意形成字符串。

  当中运用了随机数函数srand(),rand();

  但是闹腾一两个小时,自然数依然不正常。并发浏览时时间段将会基本上为同时,那样srand给的种子时间段能够当做一致的。那样就造成了,形成的自然数全是相同的。进而形成的任意字符串全是相同的。循环输出任意字符串,基本上全是完全一样的。

  然后想起了ukey,这些扩大能够构建真正的ID,那样浏览都形成真正的ID,会不会能够将这些ID当做种子时间段。结果是毫无疑问的。

  图上是形成的任意字符串,能够自定长度。也一样能够输出只有数字的字符串。相比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形成18W任意字符串常用的时间段

  图上是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);
  ?>


本文首次发布于开创者素材 ,转载请注明出处,谢谢合作!

相关文章推荐