我想在php中生成一个随机密码。
但是我得到所有'a'并且返回类型是数组类型,我希望它是一个字符串。关于如何纠正代码的任何想法?
感谢。
function randomPassword() {
$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
for ($i = 0; $i < 8; $i++) {
$n = rand(0, count($alphabet)-1);
$pass[$i] = $alphabet[$n];
}
return $pass;
}
答案 0 :(得分:235)
安全警告:
rand()
不是加密安全的伪随机数生成器。在其他地方寻找generating a cryptographically secure pseudorandom string in 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
}
答案 1 :(得分:106)
random_int()
和下面的给定random_str()
。random_int()
,请使用random_compat。由于您要生成密码,因此您需要确保生成的密码不可预测,并且确保实现中存在此属性的唯一方法是使用{{3} (CSPRNG)。
对于随机字符串的一般情况,可以放宽对CSPRNG的要求,但在涉及安全性时则不能。
在PHP中生成密码的简单,安全和正确的答案是使用cryptographically secure pseudorandom number generator并且不要重新发明轮子。该图书馆已经过行业安全专家和我自己的审核。
对于喜欢发明自己的解决方案的开发人员,PHP 7.0.0将为此提供RandomLib。如果你还在PHP 5.x上,我们写了一个random_int()
,这样你就可以在PHP 7发布之前使用新的API。使用我们的random_int()
polyfill 可能比编写自己的实现更安全。
使用安全的随机整数生成器,生成安全的随机字符串比使用派对更容易:
<?php
/**
* Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
* @return string
*/
function random_str(
$length,
$keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
) {
$str = '';
$max = mb_strlen($keyspace, '8bit') - 1;
if ($max < 1) {
throw new Exception('$keyspace must be at least two characters long');
}
for ($i = 0; $i < $length; ++$i) {
$str .= $keyspace[random_int(0, $max)];
}
return $str;
}
答案 2 :(得分:103)
我知道您正在尝试以特定方式生成密码,但您可能也想查看此方法...
$bytes = openssl_random_pseudo_bytes(2);
$pwd = bin2hex($bytes);
它取自php.net网站,它创建的字符串长度是openssl_random_pseudo_bytes函数中的两倍。所以上面会创建一个4个字符的密码。
简而言之......
$pwd = bin2hex(openssl_random_pseudo_bytes(4));
会创建长度为8个字符的密码。
但请注意,密码仅包含数字0-9和小写字母a-f!
答案 3 :(得分:52)
2行的小代码。
演示:http://codepad.org/5rHMHwnH
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return substr(str_shuffle($chars),0,$length);
}
echo rand_string(8);
使用rand_string可以定义要创建的字符数。
答案 4 :(得分:36)
如果您使用的是PHP7,则可以使用random_int()
功能:
function generate_password($length = 20){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
'0123456789`-=~!@#$%^&*()_+,./<>?;:[]{}\|';
$str = '';
$max = strlen($chars) - 1;
for ($i=0; $i < $length; $i++)
$str .= $chars[random_int(0, $max)];
return $str;
}
下面的旧答案:
function generate_password($length = 20){
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
'0123456789`-=~!@#$%^&*()_+,./<>?;:[]{}\|';
$str = '';
$max = strlen($chars) - 1;
for ($i=0; $i < $length; $i++)
$str .= $chars[mt_rand(0, $max)];
return $str;
}
答案 5 :(得分:36)
在一行中:
substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
答案 6 :(得分:26)
最好的选择是 RandomLib library by ircmaxell 。
用法示例:
$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));
$passwordLength = 8; // Or more
$randomPassword = $generator->generateString($passwordLength);
它产生的字符串比正常随机函数(如shuffle()
和rand()
更强随机(这是您通常想要的密码,盐和密钥等敏感信息)。
答案 7 :(得分:14)
我将发布一个答案,因为现有的一些答案很接近,但却有以下答案之一:
这个答案将绕过count/strlen
问题,因为生成的密码的安全性,至少是恕我直言,超越了你到达那里的方式。我也将假设PHP&gt; 5.3.0。
让我们将问题分解为以下组成部分:
对于第一部分,PHP&gt; 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))));
3/4
因素是由于base64编码导致字符串的长度至少比字节字符串大三分之一。结果将精确地$n
是4的倍数,否则最多3个字符。由于额外的字符主要是填充字符=
,如果我们由于某种原因有一个约束密码是一个确切的长度,那么我们可以将它截断到我们想要的长度。这尤其是因为对于给定的$n
,所有密码都以相同数量的密码结束,因此有权访问结果密码的攻击者最多可以猜测2个字符。
要获得额外的功劳,如果我们想要满足OP问题中的确切规范,那么我们将不得不做更多的工作。我将在这里放弃基本转换方法,然后选择快速而肮脏的方法。由于62条长字母表,两者都需要产生比结果中使用的更多的随机性。
对于结果中的额外字符,我们可以简单地从结果字符串中丢弃它们。如果我们在字节字符串中以8个字节开始,那么最多约25%的base64字符将是这些&#34;不合需要的&#34;字符,因此简单地丢弃这些字符会导致字符串不短于OP所需的字符串。然后我们可以简单地截断它以达到确切的长度:
$dirty_pass = base64_encode(strong_random_bytes(8)));
$pass = substr(str_replace(['/', '+', '='], ['', '', ''], $dirty_pass, 0, 8);
如果生成更长的密码,填充字符=
会形成较小和较小比例的中间结果,这样您就可以实现更精简的方法,如果排除用于PRNG的熵池是一个问题。< / p>
答案 8 :(得分:14)
您想要strlen($alphabet)
,而不是常量count
的{{1}}(相当于alphabet
)。
但是,'alphabet'
不是用于此目的的合适随机函数。它的输出很容易预测,因为它隐含在当前时间播种。此外,rand
不具有加密安全性;因此,从输出中确定其内部状态相对容易。
而是从rand
读取以获取加密随机数据。
答案 9 :(得分:11)
这与更简单的substr(md5(uniqid()), 0, 8);
答案 10 :(得分:11)
base_convert(uniqid('pass', true), 10, 36);
例如。 e0m6ngefmj4
修改强>
正如我在评论中提到的那样,长度意味着暴力攻击会更好地对抗它然后进行定时攻击,所以担心“随机生成器有多安全”并不是真的有意义。安全性,特别是针对此用例,需要补充可用性,因此上述解决方案实际上足以满足所需的问题。
但是,如果你在搜索安全的随机字符串生成器时偶然发现了这个答案(因为我假设有些人基于响应),对于诸如生成令牌之类的东西,这里是这样的代码的生成器将如何看起来像:
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);
}
}
答案 11 :(得分:9)
另一个(仅限linux)
function randompassword()
{
$fp = fopen ("/dev/urandom", 'r');
if (!$fp) { die ("Can't access /dev/urandom to get random data. Aborting."); }
$random = fread ($fp, 1024); # 1024 bytes should be enough
fclose ($fp);
return trim (base64_encode ( md5 ($random, true)), "=");
}
答案 12 :(得分:8)
更聪明一点:
function strand($length){
if($length > 0)
return chr(rand(33, 126)) . strand($length - 1);
}
检查here。
答案 13 :(得分:6)
使用此简单代码生成医学密码12长度
$password_string = '!@#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);
答案 14 :(得分:5)
尝试使用大写字母,小写字母,数字和特殊字符
function generatePassword($_len) {
$_alphaSmall = 'abcdefghijklmnopqrstuvwxyz'; // small letters
$_alphaCaps = strtoupper($_alphaSmall); // CAPITAL LETTERS
$_numerics = '1234567890'; // numerics
$_specialChars = '`~!@#$%^&*()-_=+]}[{;:,<.>/?\'"\|'; // Special Characters
$_container = $_alphaSmall.$_alphaCaps.$_numerics.$_specialChars; // Contains all characters
$password = ''; // will contain the desired pass
for($i = 0; $i < $_len; $i++) { // Loop till the length mentioned
$_rand = rand(0, strlen($_container) - 1); // Get Randomized Length
$password .= substr($_container, $_rand, 1); // returns part of the string [ high tensile strength ;) ]
}
return $password; // Returns the generated Pass
}
让我们说我们需要10位数传递
echo generatePassword(10);
示例输出:
,IZCQ_IV \ 7
@wlqsfhT(d
1!8 + 1 \ 4 @ UD
答案 15 :(得分:3)
快一。简单,干净和一致的格式,如果这是你想要的
$pw = chr(mt_rand(97,122)).mt_rand(0,9).chr(mt_rand(97,122)).mt_rand(10,99).chr(mt_rand(97,122)).mt_rand(100,999);
答案 16 :(得分:3)
在评论中称之为。
<?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);
}
}
?>
答案 17 :(得分:3)
这是基于此页面的另一个答案,https://stackoverflow.com/a/21498316/525649
此答案仅生成十六进制字符0-9,a-f
。对于看起来不像十六进制的东西,试试这个:
str_shuffle(
rtrim(
base64_encode(bin2hex(openssl_random_pseudo_bytes(5))),
'='
).
strtoupper(bin2hex(openssl_random_pseudo_bytes(7))).
bin2hex(openssl_random_pseudo_bytes(13))
)
base64_encode
返回更广泛的字母数字字符rtrim
有时会删除=
示例:
32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7
这对于为用户创建界面不是很容易配置,但出于某些目的,这没关系。增加字符数以解释缺少特殊字符的问题。
答案 18 :(得分:2)
我创建了一个更全面,更安全的密码脚本。这将创建两个大写,两个小写,两个数字和两个特殊字符的组合。共8个字符。
$char = [range('A','Z'),range('a','z'),range(0,9),['*','%','$','#','@','!','+','?','.']];
$pw = '';
for($a = 0; $a < count($char); $a++)
{
$randomkeys = array_rand($char[$a], 2);
$pw .= $char[$a][$randomkeys[0]].$char[$a][$randomkeys[1]];
}
$userPassword = str_shuffle($pw);
答案 19 :(得分:1)
此功能将根据参数中的规则生成密码
function random_password( $length = 8, $characters = true, $numbers = true, $case_sensitive = true, $hash = true ) {
$password = '';
if($characters)
{
$charLength = $length;
if($numbers) $charLength-=2;
if($case_sensitive) $charLength-=2;
if($hash) $charLength-=2;
$chars = "abcdefghijklmnopqrstuvwxyz";
$password.= substr( str_shuffle( $chars ), 0, $charLength );
}
if($numbers)
{
$numbersLength = $length;
if($characters) $numbersLength-=2;
if($case_sensitive) $numbersLength-=2;
if($hash) $numbersLength-=2;
$chars = "0123456789";
$password.= substr( str_shuffle( $chars ), 0, $numbersLength );
}
if($case_sensitive)
{
$UpperCaseLength = $length;
if($characters) $UpperCaseLength-=2;
if($numbers) $UpperCaseLength-=2;
if($hash) $UpperCaseLength-=2;
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$password.= substr( str_shuffle( $chars ), 0, $UpperCaseLength );
}
if($hash)
{
$hashLength = $length;
if($characters) $hashLength-=2;
if($numbers) $hashLength-=2;
if($case_sensitive) $hashLength-=2;
$chars = "!@#$%^&*()_-=+;:,.?";
$password.= substr( str_shuffle( $chars ), 0, $hashLength );
}
$password = str_shuffle( $password );
return $password;
}
答案 20 :(得分:1)
我的答案与上述类似,但我删除了元音1和0,字母i,j,I,l,O,o,Q,q,X,x,Y,y,W, w。原因是:第一个很容易混合(例如l和1,具体取决于字体),而其余的(以Q开头)是因为它们在我的语言中不存在,因此它们可能有点奇怪超级用户。字符串仍然足够长。另外,我知道使用一些特殊的标志是理想的,但是它们也与某些最终用户不相处。
struct ContentView: View {
var body: some View {
ScrollView(.vertical, showsIndicators: false){
VStack {
Text("Content View text")
Image("contentviewimage")
ForEach((1...10), id: \.self) {
user in UserCard()
}
}
}
}
}
struct UserView: View {
var body: some View {
NavigationView {
VStack {
Image("bob")
Text("Hello my name is bob")
NavigationLink(
destination: BobView()){
Text("Click me to navigate").font(.system(size: 20))
}
}
}
}
}
}
struct BobView: View{
var body: some View{
VStack{Text("bob view")}
}
}
此外,通过这种方式,我们避免重复相同的字母和数字(不包括大小写匹配)
答案 21 :(得分:0)
//define a function. It is only 3 lines!
function generateRandomPassword($length = 5){
$chars = "123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
return substr(str_shuffle($chars),0,$length);
}
//usage
echo generateRandomPassword(5); //random password legth: 5
echo generateRandomPassword(6); //random password legth: 6
echo generateRandomPassword(7); //random password legth: 7
答案 22 :(得分:0)
生成长度为8的强密码,其中至少包含一个小写字母,一个大写字母,一位数字和一个特殊字符。您也可以在代码中更改长度。
function checkForCharacterCondition($string) {
return (bool) preg_match('/(?=.*([A-Z]))(?=.*([a-z]))(?=.*([0-9]))(?=.*([~`\!@#\$%\^&\*\(\)_\{\}\[\]]))/', $string);
}
$j = 1;
function generate_pass() {
global $j;
$allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_{}[]';
$pass = '';
$length = 8;
$max = mb_strlen($allowedCharacters, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$pass .= $allowedCharacters[random_int(0, $max)];
}
if (checkForCharacterCondition($pass)){
return '<br><strong>Selected password: </strong>'.$pass;
}else{
echo 'Iteration '.$j.': <strong>'.$pass.'</strong> Rejected<br>';
$j++;
return generate_pass();
}
}
echo generate_pass();
答案 23 :(得分:0)
这是我随意使用的普通密码生成助手。
确保密码包含数字,大写和小写字母以及至少3个特殊字符。
密码的长度在11到30之间。
function plainPassword(): string
{
$numbers = array_rand(range(0, 9), rand(3, 9));
$uppercase = array_rand(array_flip(range('A', 'Z')), rand(2, 8));
$lowercase = array_rand(array_flip(range('a', 'z')), rand(3, 8));
$special = array_rand(array_flip(['@', '#', '$', '!', '%', '*', '?', '&']), rand(3, 5));
$password = array_merge(
$numbers,
$uppercase,
$lowercase,
$special
);
shuffle($password);
return implode($password);
}
答案 24 :(得分:0)
didChangeSize old: (810.0, 1080.0) new: (1080.0, 810.0)
didSetSize: (1080.0, 810.0)
didChangeSize old: (810.0, 1080.0) new: (1080.0, 810.0)
答案 25 :(得分:0)
生成随机密码串
function generate_randompassword($passlength = 8){
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#%^*>\$@?/[]=+';
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < $passlength; $i++) {
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return implode($pass); //turn the array into a string
}
答案 26 :(得分:-1)
<?php
// We can generate without large code..
$length = 8;
$chars = array_merge(range(0,9), range('a','z'),range('A','Z'),['!','@','#','$','%','&','*','?']);
//$chars = array_merge(range(0,1), range('A','Z'));
shuffle($chars);
$code = implode(array_slice($chars, 0, $length));
$arr = array($code);
$password = implode("",$arr);
echo $password;
答案 27 :(得分:-1)
如果要使用8个字符(1个大写字母和1个数字)。
$p_lc_letters = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 6); // Generate 6 lowercase letters
$p_uc_letters = substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 1); // Generate 1 uppercase letter
$p_numbers = substr(str_shuffle('0123456789'), 0, 1); // Generate 1 number
echo $password = substr(str_shuffle($p_lc_letters.''.$p_uc_letters.''.$p_numbers), 0, 8);
答案 28 :(得分:-2)
我的意思是尝试实施我自己的&#34;安全&#34;和&#34;随机&#34;密码生成器。
我认为为函数提供length
和type
参数会更有趣,更灵活。
这是一个执行一些检查的函数,以确保length
不会太短或太长(也允许可变长度)。它还允许您在type
参数中选择密码字符集。
如果null
或length
无效,则返回type
,并使用PHP&#39; mt_rand()
函数,该函数更多&#34;随机&#34;比rand()
。
<?php
/**
* Generates a random password with the given length and of the given type.
*
* @param int $length
* @param string $type
* @return string | null
*/
function random_password($length=8, $type='alpha_numeric') {
if ($length < 1 || $length > 1024) return null;
$lower = 'abcdefghijklmnopqrstuvwxy';
$upper = strtoupper($lower);
$numbers = '1234567890';
$dash = '-';
$underscore = '_';
$symbols = '`~!@#$%^&*()+=[]\\{}|:";\'<>?,./';
switch ($type) {
case 'lower':
$chars = $lower;
break;
case 'upper':
$chars = $upper;
break;
case 'numeric':
$chars = $numbers;
break;
case 'alpha':
$chars = $lower . $upper;
break;
case 'symbol':
$chars = $symbols . $dash . $underscore;
break;
case 'alpha_numeric':
$chars = $lower . $upper . $numbers;
break;
case 'alpha_numeric_dash':
$chars = $lower . $upper . $numbers . $dash;
break;
case 'alpha_numeric_underscore':
$chars = $lower . $upper . $numbers . $underscore;
break;
case 'alpha_numeric_dash_underscore':
$chars = $lower . $upper . $numbers . $underscore . $dash;
break;
case 'all':
$chars = $lower . $upper . $numbers . $underscore . $dash . $symbols;
break;
default:
return null;
}
$min = 0;
$max = strlen($chars) - 1;
$password = '';
for ($i = 0; $i < $length; $i++) {
$random = mt_rand($min, $max);
$char = substr($chars, $random, 1);
$password .= $char;
}
return $password;
}