0

I need to create a auto incrementing string similar to this randomly via php. The string is like this. So what i need is a mix of numbers and letter that is randomally generated and doesnt have to be sequential just as long as its random like this 823N9823 and it has 8 characters max

Matt Elhotiby
  • 43,028
  • 85
  • 218
  • 321

6 Answers6

3

If the characters don't need to be unique:

function randomString($length = 8, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
    $randomString = '';
    $numofChars = strlen($chars);
    while (--$length) {
        $randomString .= $chars[mt_rand(0, $numofChars - 1)];
    }
    return $randomString;
}

If the characters must be unique:

function randomString($length = 8, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') {
    return substr(str_shuffle($chars), 0, 8);
}
NikiC
  • 100,734
  • 37
  • 191
  • 225
1

usage:

echo generateRandomName();

function:

function generateRandomName($length=8,$level=2){

   list($usec, $sec) = explode(' ', microtime());
   srand((float) $sec + ((float) $usec * 100000));

   $validchars[1] = "0123456789abcdfghjkmnpqrstvwxyz";
   $validchars[2] = "0123456789abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   $validchars[3] = "0123456789_!@#$%&*()-=+/abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!@#$%&*()-=+/";

   $password  = "";
   $counter   = 0;

   while ($counter < $length) {
     $actChar = substr($validchars[$level], rand(0, strlen($validchars[$level])-1), 1);

     // All character must be different
     if (!strstr($password, $actChar)) {
        $password .= $actChar;
        $counter++;
     }
   }

   return $password;

}

Found on PHPToys

Level the level of characters to be used, 3 have special chars as $validchars[3] has.

You also can call it as: generateRandomName(5) to generate a name with length of 5.

Garis M Suero
  • 7,974
  • 7
  • 45
  • 68
1
function generateRandomString($length=8, $characters='abcdefghijklmnopqrstuvwxyz0123456789'){
   $str = '';
   $len = strlen($characters);
   for($i=0; $i<length; $i++){
      $str .= $characters[mt_rand(0, $len)];
   }
   return $string;
}

Usage:

//generates a random string, using defaults: length = 8 and characters = a-z, 0-9
echo "Your password: " . generateRandomString();
//custom length: 10
echo "Thingeys: " . generateRandomString(10);
//digits only, length 4
echo "Your PIN: " . generateRandomString(4, '0123456789');
Lekensteyn
  • 64,486
  • 22
  • 159
  • 192
1

You can use mt_rand() to generate a random integer and then transform the values into a string. The function below will give you 2 821 109 907 456 possible values.

function random_id($length = 8) {
  $validChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

  $rndString = '';

  for($i = 0; $i < $length; $i++) {
    $rndString .= $validChars[mt_rand(0, strlen($validChars) - 1)];
  }

  return $rndString;
}

$lengthEight = random_id();
$lengthTen = random_id(10);

Since there are more letters and numbers in the list of possible characters, you'll usually get a string with more letters then numbers.

If you want to skew the results towards a string with more numbers then letters, then you can use the following:

function skewed_random_id($numericFactor = 0.8, $length = 8) {
  $validAlpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $validNumeric = '0123456789';

  $rndString = '';

  for($i = 0; $i < $length; $i++) {
    if((mt_rand() / mt_getrandmax()) < $numericFactor) {
      $rndString .= $validNumeric[mt_rand(0, strlen($validNumeric) - 1)];
    } else {
      $rndString .= $validAlpha[mt_rand(0, strlen($validAlpha) - 1)];
    }
  }

  return $rndString;
}

$eightyPercentNumeric = skewed_random_id();
$fiftyFifty = skewed_random_id(0.5);
$allAlpha = skewed_random_id(0);
$allNumeric = skewed_random_id(1);
Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
0
echo substr(str_replace(array('/', '+'), '', base64_encode(sha1(uniqid(), true))), 0, 8);

Sample output:

LTeQpy9p
v11oy9R7
TjdkXZru
lh3TvNi4
X5Ca0ZXS
L01RfhxW
QDfwNnGO

you can use strtoupper and strtolower to get a version that suits your needs.


EDIT:

If you are gonna use this for something critical rather than just wanting a random string, change uniqid() into mt_rand():

echo substr(str_replace(array('/', '+'), '', base64_encode(sha1(
    mt_rand(). '.'. mt_rand(). '.'. mt_rand()%4 //256^8 of input possibilities (8 bytes)
, true))), 0, 8);
aularon
  • 11,042
  • 3
  • 36
  • 41
  • -1: While this is "random" per-say, the number of collisions you'll get is not even funny. Also, it will contain unwanted characters such as `+` or `/`. **EDIT:** You won't get unwanted characters anymore, but are still limited to a small amount of values... – Andrew Moore Sep 06 '10 at 15:03
  • @Andrew I fixed the / and + before you cast your vote/comment :) and why are you saying that it would be limited to a small amount of values? – aularon Sep 06 '10 at 15:13
  • Base64 encodes each set of 6 bytes... This means that an 8 character Base64 represents the first 6 characters of the `sha1` string `8 * 6b / 8b`. 6 sha1 hex chars have `16 777 216` possibilities (`16^6`) (so `16 777 216` possible Base64 results), which is well below the `2 821 109 907 456` possible values of a properly formatted 8 chars upper-alpha-numeric string (`36^8`). Actually, if you add lowercases, you get `218 340 105 584 896` possible values for an 8 chars alpha-numeric-string (`62^8`). – Andrew Moore Sep 06 '10 at 15:16
  • @aularon: Since your function only returns a set of `16 777 216` possible values, it is far from the `2 821 109 907 456` values of the functions located above (actually, it's about 0.0005% of the distributions you'll get above). Also, I didn't take into considerations that `uniqid` does not provide and infinite number of values, which also limit the set of possible values for the hash, which reduces your number of possible values in the end too. But that would be hard to calculate. `mt_rand()` does not increase your list of possible values. – Andrew Moore Sep 06 '10 at 15:18
  • @Andrew But I get `sha1` as binary, not as hex chars (`true` as second parameter for `sha1` in PHP does so). – aularon Sep 06 '10 at 15:23
  • @aularon: So, the maximum values you'll get out of your function now is basically the value of `mt_getrandmax()`. – Andrew Moore Sep 06 '10 at 15:30
  • @Andrew yes you are alright, thank you very much, really :) I changed the code putting `mt_rand(). '.'. mt_rand(). '.'. mt_rand()%4` instead of `mt_rand` (considering that `mt_getrandmax()` is `2147483647` which is maxmimum value for a signed 4 byte integer (32 bit machine)), won't that give me an 8 bytes (256^8) space of input possibilities? and make things okay with my code? – aularon Sep 06 '10 at 16:02
  • @aularon: That gives you `2147483647 * 4` possibilities... Assuming none of those collide when generating the hash. – Andrew Moore Sep 06 '10 at 16:18
  • @Andrew but I'm concatenating the strings, now I have a `'{a}.{b}.{c}'` string, where `{a}` has `2,147,483,647` possibilities, `{b}` has `2,147,483,647` possibilities, and `{c}` has `4` possibilities. doesn't it make the string has `2,147,483,647 * 2,147,483,647 * 4` possibilities (=`18,446,744,056,529,682,436` which is `256^8`). thanks for your patience :) – aularon Sep 06 '10 at 16:23
  • @aularon: Oups, sorry, didn't catch the double `mt_rand()`... But you have to be careful... You are basically taking the first 6 binary chars because of base64... So `2^48` assuming there is no collisions in that byte-space when you are hashing. – Andrew Moore Sep 06 '10 at 16:31
  • @Andrew, yes `2^48` is good enough compared to the output possibilities, and yes I can't do nothing about possible collisions. Thanks again : ) – aularon Sep 06 '10 at 17:04
-1
substr(uniqid(), 0, 8);

http://php.net/uniqid

erisco
  • 14,154
  • 2
  • 40
  • 45
  • uniqid isn't random. It is quite predictable (You will need to test only some thousand strings if you know the approximate time the string was generated at.) – NikiC Sep 06 '10 at 15:07
  • I think you are forgetting that, regardless, any solution is pseudo-random and thus predictable. Don't down-vote me without knowing what qualities of a RNG John really needs. – erisco Sep 06 '10 at 15:21
  • Yes, but it is still less predictable. Also, `uniqid` is limited to hexadecimal values... Therefore, your function can return `4 294 967 296` values... A far cry from the `2 821 109 907 456` possible values of the functions above. – Andrew Moore Sep 06 '10 at 15:24
  • I repeat what I already said. The debate is fine. The down-vote is completely uncalled for. – erisco Sep 06 '10 at 15:27
  • `4 294 967 296` doesn't give you a lot of leg room compared to `2 821 109 907 456` when taking about collisions and nonce. Yes, they are predictable, but a larger chance of collision is not a good thing. Higher collisions is the reason I downvoted. – Andrew Moore Sep 06 '10 at 15:32