1

Im wondering how can I go on creating a random PHP value with similar structure as IPv6

Example: 2001:0db8:85a3:0042:1000:8a2e:0370:7334:nc21

I could use mt_rand(0000,9999).":"....... and so on But this creates only numerical values, and its redundant. Is there a simpler way of doing it altha-numerically in say a function?

Thanks every one for feedback and information, in the end I choose to go with the following code bit

$randomString = sha1(dechex(mt_rand(0, 2147483647)));
$token = implode(':', str_split($randomString, 4));

Result:

9ec0:4709:926e:4cbf:fa87:2ac3:03da:f547:485b:6464

  • Use [`dechex()`](http://php.net/dechex) then, and the actual numeric span for 4 nibble hex values. – mario Jun 19 '13 at 19:16
  • What are you actually using this for? If it's just to generate a unique ID, there is the [`uniqid`](http://ca3.php.net/uniqid) function. – Tarka Jun 19 '13 at 19:19
  • Its to generate a completely random Token –  Jun 19 '13 at 19:21
  • You could randomly create either an integer (as you've already shown you know how to do) or create a character like so http://stackoverflow.com/questions/5438760/generate-random-5-characters-string. Put both of these methods into a function, and then randomly chose which one to call. Then you will have either a number or a letter, randomly. – user1477388 Jun 19 '13 at 19:21
  • @user1477388 Thanks for info, but this `$randomString = sha1(dechex(mt_rand(0, 2147483647))); $token = implode(':', str_split($randomString, 4));` works out just fine –  Jun 19 '13 at 19:23

3 Answers3

5

Avoid using rand see str_shuffle and randomness try :

echo myRand(36);

Output

023c:631e:f770:ec5b:f06b:917a:b839:4aea:45b7

Function Used

function myRand($length, $sep = ":", $space = 4) {
    if (function_exists("mcrypt_create_iv")) {
        $r = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
    } else if (function_exists("openssl_random_pseudo_bytes")) {
        $r = openssl_random_pseudo_bytes($length);
    } else if (is_readable('/dev/urandom')) {
        $r = file_get_contents('/dev/urandom', false, null, 0, $length);
    } else {
        $i = 0;
        $r = "";
        while($i ++ < $length) {
            $r .= chr(mt_rand(0, 255));
        }
    }
    return wordwrap(substr(bin2hex($r), 0, $length), $space, $sep, true);
}
Community
  • 1
  • 1
Baba
  • 94,024
  • 28
  • 166
  • 217
  • 1
    May I suggest `/dev/random` as another fallback? +1 though. – deceze Jun 19 '13 at 19:34
  • 2
    `MCRYPT_RAND = /dev/random` while `MCRYPT_DEV_URANDOM` is `/dev/urandom` ... I used ` /dev/urandom` because `/dev/random` will block after the entropy pool is exhausted – Baba Jun 19 '13 at 19:37
  • Yeah, I know, but in case both mcrypt and openssl aren't available, `is_readable('/dev/urandom') && file_get_contents('/dev/urandom', false, null, 0, $length)` is a simple fallback, probably preferable to `mt_rand`. – deceze Jun 19 '13 at 19:39
  • @deceze .. i see your point .. .. thanks would update the code in a moment – Baba Jun 19 '13 at 19:40
  • 1
    @Baba I referred your answer in case someone need secure random data instead of a simple and fast method. – TimWolla Jun 19 '13 at 19:43
2

Use a cryptografic hash-function. They output hex by default:

md5(rand()) // eg: ccc4fd993dd07dac621455c7c924d38f

Otherwards implode the return value of str_split(md5(rand()), 4) with colons to create something like this:

implode(':', str_split('ccc4fd993dd07dac621455c7c924d38f', 4));
// ccc4:fd99:3dd0:7dac:6214:55c7:c924:d38f

Depending on how many blocks you want to have random use substr to truncate the hash.


Note that this method does not create real randomness. If need need really random data have a look at the answer of Baba.

TimWolla
  • 31,849
  • 8
  • 63
  • 96
  • Pretty much exactly what I was going to suggest, except for using [`uniqid()`](http://ca3.php.net/uniqid) instead of `rand()`, since it adds an extra layer of conflict-avoidance. – Tarka Jun 19 '13 at 19:20
  • Awesome works like a charm here is what i did `$randomString = sha1(dechex(mt_rand(0, 2147483647))); $token = implode(':', str_split($randomString, 4));` –  Jun 19 '13 at 19:22
  • 1
    @user2293381 Note that `sha1` has an output size of 160bit (= 40 hexadecimal characters). IPv6 only has a size of 128bit (= 32 characters). `md5` may be besser suited! – TimWolla Jun 19 '13 at 19:24
  • @TimWolla i was mearly looking for IPv6 structure hence ":". I just did not know how to refer to it, so I just refereed to it as IPv6 structure –  Jun 19 '13 at 19:26
  • @TimWolla i know just waiting. I got 5 min limit since im a new member –  Jun 19 '13 at 19:29
  • 3
    Note that `rand()` returns a maximum of 2,147,483,647 different numbers, while `md5` has a space of 16^32. You will not efficiently fill the MD5 space with this method at all. If 2,147,483,647 different values are enough, fine; but it's not good enough for the purpose of *unique* values such as IPv6 (I know, that was just an example). – deceze Jun 19 '13 at 19:33
1

You could generate a random number between 0 and 65 535 (0xffff) and then convert it into hex using dechex.

Note that the end of your string, nc21, is not a valid hexnumber, and therefore not a valid IPv6 address.