我试图在PHP中创建一个随机字符串,我得到绝对没有输出:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
我做错了什么?
具有上面讨论的一些函数的类。
$options['numeric'] = true;
$options['uppercase'] = true;
$options['lowercase'] = true;
$new = new RandomString($options);
class RandomString
{
/**
* @var array
*/
private $default = ['numeric' => true, 'uppercase' => true, 'lowercase' => true];
/**
* @var array
*/
private $options;
/**
* array
*/
private $whitelist = ['numeric', 'uppercase', 'lowercase'];
/**
* RandomString constructor.
*
* @param array $options
*/
public function __construct(array $options = [])
{
$this->options = $this->default;
if(!empty($options))
{
$options = array_intersect_key($options, array_flip($this->whitelist));
if(empty($options))
{
$this->options = $this->default;
}else
{
$this->options = $options;
}
}
}
/**
* @return string
*/
private function returnCharacters(){
$options = $this->options;
$numbers = '0123456789';
$uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$lowercase = "abcdefghijklmnopqrstuvwxyz";
$characters = '';
if(isset($options['numeric']) && $options['numeric'] === true){
$characters .= $numbers;
}
if(isset($options['uppercase']) && $options['uppercase'] === true){
$characters .= $uppercase;
}
if(isset($options['lowercase']) && $options['lowercase'] === true){
$characters .= $lowercase;
}
return $characters;
}
/**
* @param $length
* @param $quantity
* @return string
*/
public function randomString($length, $quantity) {
$string = '';
$characters = $this->returnCharacters();
for ($j = 0; $j < $quantity; $j++) {
for($i = 0; $i < $length; $i++){
$string .= $characters[mt_rand(0, strlen($characters) - 1)];
}
$string .= "\n";
}
return $string;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @return mixed
*/
public function getWhitelist()
{
return $this->whitelist;
}
我总是喜欢使用base64来生成随机密码或其他随机(可打印的)字符串。base64的使用确保了大量的可打印字符可用。
在shell上,我通常这样做:
base64 < /dev/urandom |head -c10
在PHP中也可以做类似的事情。然而,直接从/dev/urandom读取可能会被open_basedir限制所禁止。这就是我得出的结论:
base64_encode(
join(
'',
array_map(
function($x){ return chr(mt_rand(1,255));},
range(1,15)
)
)
);
为了得到一个真正随机的字符串,我们也需要随机输入。这就是join/array_map所做的。使用uniqid之类的东西是不够的,因为它总是有一个类似的前缀,因为它基本上是一个美化的时间戳。
如果安装了openssl扩展,当然可以使用openssl_random_pseudo_bytes(),这样会更好。
这是一个简单的句子。您将得到至少一个小写字母、一个大写字母、一个数字和一个符号。使用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]来选择从哪组字符中获取随机字符。它保证数组中的每一组字符都有多个字符。
它肯定可以改进(随机设置每个字符集的数量),但对于我的目的来说已经足够好了。
具体回答这个问题,有两个问题:
当你回显$randstring时,它不在作用域内。
字符在循环中没有连接在一起。
以下是更正后的代码片段:
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[random_int(0, $charactersLength - 1)];
}
return $randomString;
}
用下面的调用输出随机字符串:
// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();
请注意,这个答案的以前版本使用rand()而不是random_int(),因此生成可预测的随机字符串。因此,根据这个答案的建议,它被更改为更安全。