我试图在PHP中创建一个随机字符串,我得到绝对没有输出:

<?php
    function RandomString()
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $randstring = '';
        for ($i = 0; $i < 10; $i++) {
            $randstring = $characters[rand(0, strlen($characters))];
        }
        return $randstring;
    }

    RandomString();
    echo $randstring;

我做错了什么?


当前回答

以前的答案会生成不安全或难以输入的密码。

这是安全的,并且提供了用户更有可能实际使用的密码,而不是因为一些薄弱的东西而被丢弃。

// NOTE: On PHP 5.x you will need to install https://github.com/paragonie/random_compat

/**
 * Generate a password that can easily be typed by users.
 *
 * By default, this will sacrifice strength by skipping characters that can cause
 * confusion. Set $allowAmbiguous to allow these characters.
 */
static public function generatePassword($length=12, $mixedCase=true, $numericCount=2, $symbolCount=1, $allowAmbiguous=false, $allowRepeatingCharacters=false)
{
  // sanity check to prevent endless loop
  if ($numericCount + $symbolCount > $length) {
    throw new \Exception('generatePassword(): $numericCount + $symbolCount are too high');
  }

  // generate a basic password with just alphabetic characters
  $chars  = 'qwertyupasdfghjkzxcvbnm';
  if ($mixedCase) {
    $chars .= 'QWERTYUPASDFGHJKZXCVBNML';
  }
  if ($allowAmbiguous) {
    $chars .= 'iol';
    if ($mixedCase) {
      $chars .= 'IO';
    }
  }

  $password = '';
  foreach (range(1, $length) as $index) {
    $char = $chars[random_int(0, strlen($chars) - 1)];

    if (!$allowRepeatingCharacters) {
      while ($char == substr($password, -1)) {
        $char = $chars[random_int(0, strlen($chars) - 1)];
      }
    }

    $password .= $char;
  }


  // add numeric characters
  $takenSubstitutionIndexes = [];

  if ($numericCount > 0) {
    $chars = '23456789';
    if ($allowAmbiguous) {
      $chars .= '10';
    }

    foreach (range(1, $numericCount) as $_) {
      $index = random_int(0, strlen($password) - 1);
      while (in_array($index, $takenSubstitutionIndexes)) {
        $index = random_int(0, strlen($password) - 1);
      }

      $char = $chars[random_int(0, strlen($chars) - 1)];
      if (!$allowRepeatingCharacters) {
        while (substr($password, $index - 1, 1) == $char || substr($password, $index + 1, 1) == $char) {
          $char = $chars[random_int(0, strlen($chars) - 1)];
        }
      }

      $password[$index] = $char;
      $takenSubstitutionIndexes[] = $index;
    }
  }

  // add symbols
  $chars = '!@#$%&*=+?';
  if ($allowAmbiguous) {
    $chars .= '^~-_()[{]};:|\\/,.\'"`<>';
  }

  if ($symbolCount > 0) {
    foreach (range(1, $symbolCount) as $_) {
      $index = random_int(0, strlen($password) - 1);
      while (in_array($index, $takenSubstitutionIndexes)) {
        $index = random_int(0, strlen($password) - 1);
      }

      $char = $chars[random_int(0, strlen($chars) - 1)];
      if (!$allowRepeatingCharacters) {
        while (substr($password, $index - 1, 1) == $char || substr($password, $index + 1, 1) == $char) {
          $char = $chars[random_int(0, strlen($chars) - 1)];
        }
      }

      $password[$index] = $char;
      $takenSubstitutionIndexes[] = $index;
    }
  }

  return $password;
}

其他回答

一个班轮。

对于具有唯一性的大字符串,它是快速的。

function random_string($length){
    return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
function randomString() {
       return md5(rand(100, 200));
}

这是一个简单的句子。您将得到至少一个小写字母、一个大写字母、一个数字和一个符号。使用random_int,这应该是密码安全的。不过,我并不认为这是安全的。我不是安全专家。

复制+粘贴:(只需将$len更改为所需的长度。)

$len=26;for ($chars = array('0123456789','abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ','!@#$%^&*()_+-='),$randomString="",$i=0;$i<$len;$i++)$randomString .= substr($chars[$i%4], random_int(0,strlen($chars[$i%4])), 1);
echo $randomString;

再细分一下:

for (
        $chars = array('0123456789','abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ','!@#$%^&*()_+-='),
        $randomString="",
        $i=0;
        $i<12;$i++)
        $randomString .= 
            substr($chars[$i%4], 
                random_int(0, strlen($chars[$i%4])), 1);

我在循环中使用$chars[$ I %4]来选择从哪组字符中获取随机字符。它保证数组中的每一组字符都有多个字符。

它肯定可以改进(随机设置每个字符集的数量),但对于我的目的来说已经足够好了。

一个非常快速的方法是这样做:

substr(md5(rand()),0,10);

这将生成一个长度为10个字符的随机字符串。当然,有些人可能会说这在计算方面有点重,但现在的处理器已经优化到可以快速运行md5或sha256算法。当然,如果rand()函数返回相同的值,结果将是相同的,有1 / 32767的机会是相同的。如果安全性是问题,那么只需将rand()更改为mt_rand()

使用random_bytes函数生成加密安全的随机字节。

$bytes = random_bytes(16);
echo bin2hex($bytes);

可能的输出

da821217e61e33ed4b2dd96f8439056c

使用openssl_random_pseudo_bytes函数生成伪随机字节。

$bytes = openssl_random_pseudo_bytes(16);
echo bin2hex($bytes);

可能的输出

e2d1254506fbb6cd842cd640333214ad

最好的用例是

function getRandomBytes($length = 16)
{
    if (function_exists('random_bytes')) {
        $bytes = random_bytes($length / 2);
    } else {
        $bytes = openssl_random_pseudo_bytes($length / 2);
    }
    return bin2hex($bytes);
}
echo getRandomBytes();

可能的输出

ba8cc342bdf91143