【问题标题】:Generator for random long hex strings in PHPPHP中随机长十六进制字符串的生成器
【发布时间】:2012-11-06 13:44:18
【问题描述】:

我已经编写了一个字符串生成器,但我不知道如何创建一个长度(例如 100 位)的 随机十六进制 字符串以插入数据库。所有这些字符串的长度必须相同。

如何生成随机十六进制字符串?

【问题讨论】:

  • 您当前的发电机是如何工作的?例如,如果它当前从字符串“ABC..XYZ”中获取一个随机字符,为什么不将其更改为“0123456789ABCDEF”?您应该可以轻松修改它。
  • 为什么不能使用每个字符串 100 个循环的循环,并使用 random() 生成 0 到 15 之间的随机数并将其转换为适当的十六进制字符?
  • @arkascha 听起来很不错,你能把你的代码放在那里吗,我是 php 的初学者,我会感谢一切。请问您是如何意识到这一点的?
  • 好吧,看看下面@WebnetMobile.com 给出的答案。他完全按照我的建议编写代码。
  • <?php $val = ''; for( $i=0; $i<100; $i++ ) { $val .= chr( rand( 65, 90 ) ); echo"<br>".sha1(($val)); } ?> 是的,它有效!:) 输出例如:72c8e80ba38c19ca2724c2ca33ffa651fa3fdafc 我怎样才能获得更大的字符串?:)

标签: php generator


【解决方案1】:

虽然这回答了 OP 的问题,但如果您正在寻找的是随机,那么@danorton 的答案可能更合适。


像这样:

$val = '';
for( $i=0; $i<100; $i++ ) {
   $val .= chr(rand(65, 90));
}

65 是 A,而 90 是 Z。如果你不喜欢“幻数”,这个表格可能更易读:

$val = '';
for( $i=0; $i<100; $i++ ) {
   $val .= chr(rand(ord('A'), ord('Z')));
}

出于性能原因,我会将 ord() 作为一个变量并将其移出循环:

$A = ord('A');
$Z = ord('Z');
$val = '';
for( $i=0; $i<100; $i++ ) {
   $val .= chr(rand($A, $Z));
}

或者您可以粘贴sha1()s(其中三个)的输出并减少到 100 个字符。或者改用md5()(但我会坚持使用sha1())。

EDIT sha1() 输出 40 个字符长的字符串,md5() 32 个字符长。因此,如果您不想逐个字符地粘合字符(如我上面给出的循环),请尝试此功能

function getId($val_length) {
    $result = '';
    $module_length = 40;   // we use sha1, so module is 40 chars
    $steps = round(($val_length/$module_length) + 0.5);

    for( $i=0; $i<$steps; $i++ ) {
      $result .= sha1(uniqid() . md5(rand());
    }

    return substr($result, 0, $val_length);
}

其中函数参数是要返回的字符串的长度。叫它getId(100);

【讨论】:

  • ".sha1(($val)); } ?> 是的,它有效!:) 输出例如:72c8e80ba38c19ca2724c2ca33ffa651fa3fdafc 我怎样才能得到更大的字符串?:)
  • 添加两个 uniqid() 没有影响。一个就足够了。有趣的是,没有任何冲突会使冲突增加 3 倍。在 1000 万个样本大小中,您的代码平均有大约 11,000 次冲突(两个或一个 uniqid() 没有区别)。删除 uniqid() 并且冲突增加到 35,000。无论哪种方式,这都是 99.89% 的无碰撞几率和 99.65% 的几率之间的差异。
【解决方案2】:

衬线技术可以做到这一点,但它有点复杂并且在字符串长度方面是硬编码的。

$rand4 = substr(sha1(rand(0,getrandmax())),rand(0,24),16);

如果你想改变输出字符串的长度,你需要改变函数的最后一个变量(我设置为 16),另外还有一个 rand(0,24),其中数字 24 会改变根据第三个变量,它不应该超过 40-thirdvariable...

【讨论】:

    【解决方案3】:

    从带有 OpenSSL 扩展的 PHP 5.3 开始:

    function getRandomHex($num_bytes=4) {
      return bin2hex(openssl_random_pseudo_bytes($num_bytes));
    }
    

    以 100 位为例:

    $str = getRandomHex(50);
    

    【讨论】:

    • 这是最好的答案。
    • 我同意这是最安全的方式,但取决于用例(当安全不是问题时)我更喜欢不需要额外 PHP 扩展的解决方案(ext-openssl in本例)
    【解决方案4】:
    $randHexStr = implode( array_map( function() { return dechex( mt_rand( 0, 15 ) ); }, array_fill( 0, $strlen, null ) ) );
    

    其中 $strlen 是随机十六进制字符串的长度。

    【讨论】:

      【解决方案5】:

      我喜欢有一个可以处理类似情况的通用函数。我的意思是一个函数,它接收生成的字符串的所需长度和其中可能出现的字符。

      这样一个函数就可以创建:40位十进制数、16位大写十六进制数、100个字母小写字符串等...

      这是我的实现:

      /**
       * Generate a random string.
       *
       * @param int    $length Length of the generated string.
       * @param string $chars  The string containing all of the available characters.
       *
       * @return string The generated string.
       */
      function getRandomString($length = 10, $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
          $str = '';
      
          $size = strlen($chars);
          for ($i = 0; $i < $length; $i++) {
              $str .= $chars[mt_rand(0, $size - 1)];
          }
      
          return $str;
      }
      

      重要提示:请勿出于任何安全目的使用此函数生成随机字符串。对于安全的字符串生成器,请查看@danorton 的答案。

      【讨论】:

        猜你喜欢
        • 2012-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 2010-11-06
        • 2015-10-07
        相关资源
        最近更新 更多