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

5
  • Use dechex() then, and the actual numeric span for 4 nibble hex values. Commented Jun 19, 2013 at 19:16
  • What are you actually using this for? If it's just to generate a unique ID, there is the uniqid function. Commented Jun 19, 2013 at 19:19
  • Its to generate a completely random Token Commented Jun 19, 2013 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 stackoverflow.com/questions/5438760/…. 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. Commented Jun 19, 2013 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 Commented Jun 19, 2013 at 19:23

3 Answers 3

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);
}
Sign up to request clarification or add additional context in comments.

5 Comments

May I suggest /dev/random as another fallback? +1 though.
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
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 .. i see your point .. .. thanks would update the code in a moment
@Baba I referred your answer in case someone need secure random data instead of a simple and fast method.
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.

6 Comments

Pretty much exactly what I was going to suggest, except for using uniqid() instead of rand(), since it adds an extra layer of conflict-avoidance.
Awesome works like a charm here is what i did $randomString = sha1(dechex(mt_rand(0, 2147483647))); $token = implode(':', str_split($randomString, 4));
@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 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
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).
|
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.

1 Comment

I know, I just used it as reference. Sorry about that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.