Last Updated: February 25, 2016
·
909
· darkmantiscs

Random String/Code Generator

This was a function written by a friend of mine for the CMS we work on.

I hope it can be useful to somebody.

/**
 * Generates a random code
 *
 * @version 2.0
 * @since   0.6.0
 *
 * @param   int         $maxLength
 *
 * @return  string
 */
function randCode($maxLength=6){
    $password = NULL;
    $possible = 'bcdfghjkmnrstvwxyz123456789';
    $i = 0;
    while(($i < $maxLength) && (strlen($possible) > 0)){ $i++;
        $character = substr($possible, mt_rand(0, strlen($possible)-1), 1);
        $password .= $character;
    }
    return $password;
}

7 Responses
Add your response

I made something similar a few days ago, with the added feature of generating strings with a high tendency to include more common characters.

function generate_string($length = 7, $variance = 5, $weight = 3) {
    $length += rand(0 - $variance, $variance);
    $l0 = str_split('tashwiobmfcldpnegryuvjkqxz');
    $l = str_split('etaoinshrdlcumwfgypbvkjxqz.');

    $str = '';
    for ($i = 0; $i < $length; $i++) {
        $a = $i == 0 ? $l0 : $l;
        $s = count($a);
        for ($r = 1; $r < $weight; $r++) {
            $s = min(count($a) - 1, rand(0, $s));
        }

        $str .= $a[$s];
    }
    return $str;
}

It's used for generating test data so the code is fairly shoddy (especially variable naming), but the output is solid.

over 1 year ago ·

@richthegeek Seems like we have a very similar function all in all. Even the purpose. I used mine to create test data as well as session IDs for my Session Class which was then MD5'd (+ salt).

I would be interested in the performance output of each to be honest. I might do a test on them and get back to you.

over 1 year ago ·

@richthegeek Okay, I've done a bench mark on the two functions and mine is marginally faster than yours (tried to make the test as even as possible).

However, yours does seem to be a more thought out function which would return a better result.

------- Bench for generate_string() ------
0.84907793998718
------- </of> Bench for generate_string() ------

------- Bench for randCode() ------
0.33225393295288
------- </of> Bench for randCode() ------

Result : http://codepad.org/IQJSuY7A

over 1 year ago ·

Mine has the inner loop for weighting towards the start of the range - this could be done more efficiently (and more tunable) with logs or similar, but really any weighting will introduce a cost.

Ultimately, for test data, "human-ness" is pretty unimportant. And if you want to get it looking even close to reasonable, you need to use markov chains.

over 1 year ago ·

Something like the following provides a good weighted value, which can be modified by changing 2 to something larger/smaller (within reason).

$char = $len - round(log(pow(rand(0,$len),2))*$len*(1/2))

That would almost definitely be faster, even with the log.

over 1 year ago ·

Improved version that still has the weighting towards the start:

function generate_string($length = 6, $variance = 3, $weight = 2) {
    $length += rand(0 - $variance, $variance);
    $l0 = str_split('tashwiobmfcldpnegryuvjkqxz');
    $l = str_split('etaoinshrdlcumwfgypbvkjxqz.');

    $str = '';
    for ($i = 0; $i < $length; $i++) {
        $a = $i == 0 ? $l0 : $l;
        $len = count($a) - 1;
        $s = ceil($len - ($len * log(rand(0, $len), $len)));

        $str .= $a[$s];
    }
    return $str;
}

Timings:

Dark: 0.12173390388489
Rich:0.15515804290771
over 1 year ago ·

@richthegeek It's always good to see someone who can really optimize their code effectively.

Thanks for the update as well, it's always appreciated.

I personally don't think that there is really that much in either of them, even before you optimized your code, if anything I would lean towards using your function over mine, even at the extra cost of 0.03* seconds. Solely because yours does a better job than mine does.

Good work!

over 1 year ago ·