我试图在php中生成一个随机密码。

但是我得到的都是'a'返回类型是数组类型,我希望它是字符串。对如何修改代码有什么想法吗?

谢谢。

function randomPassword() {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    for ($i = 0; $i < 8; $i++) {
        $n = rand(0, count($alphabet)-1);
        $pass[$i] = $alphabet[$n];
    }
    return $pass;
}

当前回答

使用这个简单的代码生成med-strong密码长度为12

$password_string = '!@#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);

其他回答

Base_convert (uniqid('pass', true), 10,36);

我。e0m6ngefmj4

EDIT

正如我在评论中提到的,长度意味着暴力攻击比定时攻击更有效,所以不必担心“随机生成器有多安全”。安全性,特别是对于这个用例,需要补充可用性,所以上面的解决方案对于所需的问题已经足够好了。

然而,以防你在搜索安全的随机字符串生成器时偶然发现了这个答案(我假设有些人已经基于响应),对于生成令牌之类的东西,以下是此类代码的生成器的样子:

function base64urlEncode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function secureId($length = 32) {

    if (function_exists('openssl_random_pseudo_bytes')) {
        $bytes = openssl_random_pseudo_bytes($length);
        return rtrim(strtr(base64_encode($bytes), '+/', '0a'), '=');
    }
    else { // fallback to system bytes

        error_log("Missing support for openssl_random_pseudo_bytes");

        $pr_bits = '';

        $fp = @fopen('/dev/urandom', 'rb');
        if ($fp !== false) {
            $pr_bits .= @fread($fp, $length);
            @fclose($fp);
        }

        if (strlen($pr_bits) < $length) {
            error_log('unable to read /dev/urandom');
            throw new \Exception('unable to read /dev/urandom');
        }

        return base64urlEncode($pr_bits);
    }
}

Create a file with this code in it. Call it like in the comments. <?php /** * @usage : * include_once($path . '/Password.php'); * $Password = new Password; * $pwd = $Password->createPassword(10); * return $pwd; * */ class Password { public function createPassword($length = 15) { $response = []; $response['pwd'] = $this->generate($length); $response['hashPwd'] = $this->hashPwd( $response['pwd'] ); return $response; } private function generate($length = 15) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(){}/?,><"; return substr(str_shuffle($chars),0,$length); } private function hashPwd($pwd) { return hash('sha256', $pwd); } } ?>

安全警告:rand()不是一个加密安全的伪随机数生成器。在其他地方寻找在PHP中生成加密安全的伪随机字符串的方法。

试试这个(使用strlen而不是count,因为count在字符串上总是1):

function randomPassword() {
    $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
    $pass = array(); //remember to declare $pass as an array
    $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
    for ($i = 0; $i < 8; $i++) {
        $n = rand(0, $alphaLength);
        $pass[] = $alphabet[$n];
    }
    return implode($pass); //turn the array into a string
}

Demo

我将发布一个答案,因为现有的一些答案很接近,但有一个:

一个比你想要的更小的字符空间,这样在相同的熵下,强制操作更容易,或者密码必须更长 不被认为是加密安全的RNG 一些第三方库的需求,我认为这可能是有趣的,展示什么可能需要自己做

这个答案将规避计数/strlen问题,因为生成的密码的安全性,至少在我看来,超越了你如何到达那里。我还将假设PHP > 5.3.0。

让我们把这个问题分解成几个组成部分:

使用一些安全的随机来源来获取随机数据 使用该数据并将其表示为一些可打印的字符串

对于第一部分,PHP > 5.3.0提供了函数openssl_random_pseudo_bytes。注意,虽然大多数系统使用加密强算法,但你必须检查,所以我们将使用包装器:

/**
 * @param int $length
 */
function strong_random_bytes($length)
{
    $strong = false; // Flag for whether a strong algorithm was used
    $bytes = openssl_random_pseudo_bytes($length, $strong);

    if ( ! $strong)
    {
        // System did not use a cryptographically strong algorithm 
        throw new Exception('Strong algorithm not available for PRNG.');
    }        

    return $bytes;
}

对于第二部分,我们将使用base64_encode,因为它接受一个字节字符串,并将生成一系列字母非常接近原始问题中指定的字母的字符。如果我们不介意在最后的字符串中出现+,/和=字符,并且我们希望结果至少有$n个字符长,我们可以简单地使用:

base64_encode(strong_random_bytes(intval(ceil($n * 3 / 4))));

The 3/4 factor is due to the fact that base64 encoding results in a string that has a length at least a third bigger than the byte string. The result will be exact for $n being a multiple of 4 and up to 3 characters longer otherwise. Since the extra characters are predominantly the padding character =, if we for some reason had a constraint that the password be an exact length, then we can truncate it to the length we want. This is especially because for a given $n, all passwords would end with the same number of these, so that an attacker who had access to a result password, would have up to 2 less characters to guess.


对于额外的学分,如果我们想要满足OP的问题中的确切规格,那么我们将不得不做更多的工作。在这里我将放弃碱基转换方法,而使用一个快速而肮脏的方法。这两种方法都需要产生比结果中所使用的更多的随机性,因为字母表有62个条目。

对于结果中的额外字符,我们可以简单地将它们从结果字符串中丢弃。如果我们在字节串中开始有8个字节,那么多达25%的base64字符将是这些“不受欢迎的”字符,因此简单地丢弃这些字符将导致不少于OP所需的字符串。然后我们可以简单地截断它以得到准确的长度:

$dirty_pass = base64_encode(strong_random_bytes(8)));
$pass = substr(str_replace(['/', '+', '='], ['', '', ''], $dirty_pass, 0, 8);

如果您生成较长的密码,填充字符=在中间结果中所占的比例会越来越小,这样您就可以实现更精简的方法(如果需要耗尽用于PRNG的熵池)。

我的答案与上面的一些类似,但我去掉了元音,数字1和0,字母I, j, I, l, O, O, Q, Q, X, X, Y, Y, W, W。原因是:第一个很容易混淆(就像l和1,取决于字体),其余的(从Q开始)是因为它们在我的语言中不存在,所以对于超级终端用户来说可能有点奇怪。字符串仍然足够长。此外,我知道使用一些特殊的标志是理想的,但他们也与一些最终用户相处不好。

function generatePassword($length = 8) {

$chars = '23456789bcdfhkmnprstvzBCDFHJKLMNPRSTVZ';
$shuffled = str_shuffle($chars);
$result = mb_substr($shuffled, 0, $length);

return $result;
}

此外,通过这种方式,我们避免重复相同的字母和数字(不包括匹配情况)