[php] Generate random 5 characters string

I want to create exact 5 random characters string with least possibility of getting duplicated. What would be the best way to do it? Thanks.

This question is related to php random

The answer is


I always use the same function for this, usually to generate passwords. It's easy to use and useful.

function randPass($length, $strength=8) {
    $vowels = 'aeuy';
    $consonants = 'bdghjmnpqrstvz';
    if ($strength >= 1) {
        $consonants .= 'BDGHJLMNPQRSTVWXZ';
    }
    if ($strength >= 2) {
        $vowels .= "AEUY";
    }
    if ($strength >= 4) {
        $consonants .= '23456789';
    }
    if ($strength >= 8) {
        $consonants .= '@#$%';
    }

    $password = '';
    $alt = time() % 2;
    for ($i = 0; $i < $length; $i++) {
        if ($alt == 1) {
            $password .= $consonants[(rand() % strlen($consonants))];
            $alt = 0;
        } else {
            $password .= $vowels[(rand() % strlen($vowels))];
            $alt = 1;
        }
    }
    return $password;
}

$str = '';
$str_len = 8;
for($i = 0, $i < $str_len; $i++){
    //97 is ascii code for 'a' and 122 is ascii code for z
    $str .= chr(rand(97, 122));
}
return $str

You can try it simply like this:

$length = 5;

$randomletter = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, $length);

more details: http://forum.arnlweb.com/viewtopic.php?f=7&t=25


If it's fine that you'll get only letters A-F, then here's my solution:

str_pad(dechex(mt_rand(0, 0xFFFFF)), 5, '0', STR_PAD_LEFT);

I believe that using hash functions is an overkill for such a simple task as generating a sequence of random hexadecimal digits. dechex + mt_rand will do the same job, but without unnecessary cryptographic work. str_pad guarantees 5-character length of the output string (if the random number is less than 0x10000).

Duplicate probability depends on mt_rand's reliability. Mersenne Twister is known for high-quality randomness, so it should fit the task well.


A speedy way is to use the most volatile characters of the uniqid function.

For example:

$rand = substr(uniqid('', true), -5);

works fine in PHP (php 5.4.4)

$seed = str_split('abcdefghijklmnopqrstuvwxyz');
$rand = array_rand($seed, 5);
$convert = array_map(function($n){
    global $seed;
    return $seed[$n];
},$rand);

$var = implode('',$convert);
echo $var;

Live Demo


function CaracteresAleatorios( $Tamanno, $Opciones) {
    $Opciones = empty($Opciones) ? array(0, 1, 2) : $Opciones;
    $Tamanno = empty($Tamanno) ? 16 : $Tamanno;
    $Caracteres=array("0123456789","abcdefghijklmnopqrstuvwxyz","ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    $Caracteres= implode("",array_intersect_key($Caracteres, array_flip($Opciones)));
    $CantidadCaracteres=strlen($Caracteres)-1;
    $CaracteresAleatorios='';
    for ($k = 0; $k < $Tamanno; $k++) {
        $CaracteresAleatorios.=$Caracteres[rand(0, $CantidadCaracteres)];
    }
    return $CaracteresAleatorios;
}

The following should provide the least chance of duplication (you might want to replace mt_rand() with a better random number source e.g. from /dev/*random or from GUIDs):

<?php
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $result = '';
    for ($i = 0; $i < 5; $i++)
        $result .= $characters[mt_rand(0, 61)];
?>

EDIT:
If you are concerned about security, really, do not use rand() or mt_rand(), and verify that your random data device is actually a device generating random data, not a regular file or something predictable like /dev/zero. mt_rand() considered harmful:
https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php

EDIT: If you have OpenSSL support in PHP, you could use openssl_random_pseudo_bytes():

<?php
    $length = 5;
    $randomBytes = openssl_random_pseudo_bytes($length);
    $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    $charactersLength = strlen($characters);
    $result = '';
    for ($i = 0; $i < $length; $i++)
        $result .= $characters[ord($randomBytes[$i]) % $charactersLength];
?>

I`ve aways use this:

<?php function fRand($len) {
    $str = '';
    $a = "abcdefghijklmnopqrstuvwxyz0123456789";
    $b = str_split($a);
    for ($i=1; $i <= $len ; $i++) { 
        $str .= $b[rand(0,strlen($a)-1)];
    }
    return $str;
} ?>

When you call it, sets the lenght of string.

<?php echo fRand([LENGHT]); ?>

You can also change the possible characters in the string $a.


Here are my random 5 cents ...

$random=function($a, $b) {
    return(
        substr(str_shuffle(('\\`)/|@'.
        password_hash(mt_rand(0,999999),
        PASSWORD_DEFAULT).'!*^&~(')),
        $a, $b)
    );
};

echo($random(0,5));

PHP's new password_hash() (* >= PHP 5.5) function is doing the job for generation of decently long set of uppercase and lowercase characters and numbers.

Two concat. strings before and after password_hash within $random function are suitable for change.

Paramteres for $random() *($a,$b) are actually substr() parameters. :)

NOTE: this doesn't need to be a function, it can be normal variable as well .. as one nasty singleliner, like this:

$random=(substr(str_shuffle(('\\`)/|@'.password_hash(mt_rand(0,999999), PASSWORD_DEFAULT).'!*^&~(')), 0, 5));

echo($random);

I also did not know how to do this until I thought of using PHP array's. And I am pretty sure this is the simplest way of generating a random string or number with array's. The code:

function randstr ($len=10, $abc="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789") {
    $letters = str_split($abc);
    $str = "";
    for ($i=0; $i<=$len; $i++) {
        $str .= $letters[rand(0, count($letters)-1)];
    };
    return $str;
};

You can use this function like this

randstr(20)     // returns a random 20 letter string
                // Or like this
randstr(5, abc) // returns a random 5 letter string using the letters "abc"

If for loops are on short supply, here's what I like to use:

$s = substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", 5)), 0, 5);

Source: PHP Function that Generates Random Characters

This simple PHP function worked for me:

function cvf_ps_generate_random_code($length=10) {

   $string = '';
   // You can define your own characters here.
   $characters = "23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";

   for ($p = 0; $p < $length; $p++) {
       $string .= $characters[mt_rand(0, strlen($characters)-1)];
   }

   return $string;

}

Usage:

echo cvf_ps_generate_random_code(5);

Similar to Brad Christie's answer, but using sha1 alrorithm for characters 0-9a-zA-Z and prefixed with a random value :

$str = substr(sha1(mt_rand() . microtime()), mt_rand(0,35), 5);

But if you have set a defined (allowed) characters :

$validChars = array('0','1','2' /*...*/,'?','-','_','a','b','c' /*...*/);
$validCharsCount = count($validChars);

$str = '';
for ($i=0; $i<5; $i++) {
    $str .= $validChars[rand(0,$validCharsCount - 1)];
}

** UPDATE **

As Archimedix pointed out, this will not guarantee to return a "least possibility of getting duplicated" as the number of combination is low for the given character range. You will either need to increase the number of characters, or allow extra (special) characters in the string. The first solution would be preferable, I think, in your case.


It seems like str_shuffle would be a good use for this. Seed the shuffle with whichever characters you want.

$my_rand_strng = substr(str_shuffle("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), -5);