Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

random_bytes can be unique ? collision percentage?

Tags:

I searched here, but I found nothing about my question. So, here I am posting this beginner-like question. Is random_bytes() can be unique ? is it collision proof? or at least percentage of collision ? that's all thank you.

like image 392
phew Avatar asked May 28 '16 08:05

phew


People also ask

Is random_ bytes unique?

Since random_bytes is a pseudo-random generator that depends on the OS, never assume that the generated string is unique, always add a check before using the data.

What is Random_bytes?

The random_bytes()is an inbuilt function in PHP. The main function is to generate cryptographically secure pseudo-random bytes. It generates cryptographic random bytes of arbitrary string length. The different sources of randomness used in this function, they are as follows:- Window : CryptGenRandom() function.

Is PHP Random_bytes secure?

Using Random Numbers to Generate Random Strings Since random_str() uses random_int() , which uses random_bytes() , which is in turn cryptographically secure, we can guarantee that the strings it produce have a uniform distribution of possible values which do not follow a predictable pattern.


2 Answers

According to the manual:

Generates an arbitrary length string of cryptographic random bytes that are suitable for cryptographic use

So you can assume uniqueness, of course depending on the length of generated string. If you need to generate ID, then look at UUIDv4 e.g., and follow its generation algorithm, then you should be mostly safe.

like image 166
michaJlS Avatar answered Nov 15 '22 16:11

michaJlS


I made a totally unscientific test using this script:

<?php

// collisions.php -- check collisions of random_bytes()

set_time_limit(0);

if(count($argv) < 2) die("Usage: php collisions.php n\n       where n is the number of tries\n");

$tries = floatval($argv[1]);
if($tries < 1) die("Number of tries must be at least 1.\n");

$t = time();

$chkUnqiue = [];
for($i = 0; $i < $tries; $i++) {
   $r = bin2hex(random_bytes(16));
   if(isset($chkUnique[$r]))
      $chkUnique[$r]++;
   else
      $chkUnique[$r] = 0;
}

$t = time() - $t;

echo "Collisions by random_bytes() after " . number_format($tries) . " tries: " .
     array_sum($chkUnique) .
     "\nTook approx. $t sec.\n";

And tried it for up to 30 million runs:

php collisions.php 30000000

And the output was:

Collisions by random_bytes() after 30,000,000 tries: 0
Took approx. 53 sec.

Beyond 30 million, it started throwing out of memory errors. Running in CLI mode, I had the memory limit set to -1 (unlimited) so I had no room for larger tests on that server ... maybe someone can confirm no collisions on larger number of trials?

like image 23
A. Genedy Avatar answered Nov 15 '22 16:11

A. Genedy