Reputation: 215
I have to generate a random string with a fixed length of 10 characters. But the trick is that it must contain at least one lowercase letter, one uppercase one, a digit and one of these symbols: `~!@#$%^&*()_-+={}[]|:;"'<>,.?/
I used this simple function before:
function generateRandomString($length = 10)
{
$characters='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()_-+={}[]|:;"\'<>,.?/';
$result = '';
for ($i = 0; $i < $length; $i++)
$result .= $characters[rand(0, strlen($characters) - 1)];
return $result;
}
But this function doesn't include at least one of each character type needed. Even if I go another route:
function generateRandomString($length = 10)
{
$dig = '0123456789';
$low = 'abcdefghijklmnopqrstuvwxyz';
$upp = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$sym = '`~!@#$%^&*()_-+={}[]|:;"\'<>,.?/';
$result = '';
for ($i = 0; $i < $length; $i++)
{
$foo = rand(1,4);
switch ($foo)
{
case 1:
$result .= $dig[rand(0, strlen($dig)-1)];
break;
case 2:
$result .= $low[rand(0, strlen($low)-1)];
break;
// etc.
}
return $result;
}
This still wouldn't necessarily contain at least one of each. All the characters must be randomly placed. So any help would be much appreciated. Thank you.
Upvotes: 1
Views: 337
Reputation: 1380
If your generator doesn't need to be very fast, you could do something like this:
do {
$string = generateRandomString(10);
} while(!check_password_rules($string))
function check_password_rules($string) {
// return true if password fits policy
}
It has the advantage that you don't sacrifice any randomness by setting fixed probabilities for character groups.
Upvotes: 2
Reputation: 458
You can build your list and then use str_shuffle
. I'm sure this can be simplified and written a bit better, but this works.
I added a percentage method so you can have a certain percentage of each characters.
function generateRandomString($length = 10) {
$result = getRandomString(.2 * $length, '0123456789');
$result .= getRandomString(.3 * $length, 'abcdefghijklmnopqrstuvwxyz');
$result .= getRandomString(.3 * $length, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
$result .= getRandomString(.2 * $length, '`~!@#$%^&*()_-+={}[]|:;"\'<>,.?/');
$str_len = strlen($result);
if($str_len != $length) $result .= getRandomString($length - $str_len, 'abcdefghijklmnopqrstuvwxyz');
return str_shuffle($result);
}
function getRandomString($length, $characters) {
$result = '';
$strlen = strlen($characters);
for($i = 0; $i < floor($length); $i++) $result .= $characters[rand(0, $strlen - 1)];
return $result;
}
echo generateRandomString(31);
Upvotes: 2
Reputation: 22904
I don't quite know PHP, but I imagine you could do something like this (forgive syntax errors):
$result = "";
$result .= $dig[rand(0, strlen($dig) - 1];
$result .= $low[rand(0, strlen($low) - 1];
$result .= $upp[rand(0, strlen($upp) - 1];
$result .= $sym[rand(0, strlen($sym) - 1];
// at this point, you have one of each
// Go through your for loop 6 more times, and then finally:
$result = str_shuffle($result)
Hope that helps. str_shuffle seems like it would be useful.
Upvotes: 5