PHP - uniqid(“”,true) versus uniqid(“”)+mt_rand()

2020-04-20 21:17发布

What are the key differences between these two approaches to generate sequential-but-somewhat-unique numbers? I want to use such a number as a unique user ID inside a MySQL db, and also as a salt to salt a password.

My understanding is that for clustering and indexing reasons those IDs should be sequential (I realize that in some cases the random string will make two entries that occurred in the same microsecond non sequential, but hopefully this is negligible.)

2条回答
爷、活的狠高调
2楼-- · 2020-04-20 21:31

Without using more entropy, uniqid does basically the following (see source of uniqid.c):

$time = explode(' ', microtime(false));
return sprintf('%s%08x%05x', $prefix, $time[1], $time[0] * 1000000);

So it basically takes the current time in microseconds and turns them into a hexadecimal representation and appends it to the prefix. This does already provide unique values.

But the values are not quite random. For getting more random values, you should add more entropy by setting the second parameter more_entropy. In that case PHP’s internal linear congruential generator php_combined_lcg (see source of lgc.c) is used to generate a pseudo-random number that is attached at the end, adding circa 30 bits of additional entropy to make them more random.

查看更多
一纸荒年 Trace。
3楼-- · 2020-04-20 21:32

(scratch this, wrong info, sorry)

So yes, as Gumbo pointed out, it's not a hash but indeed a microsecond resolution increasing timer value, optionally concatenated with a random number. So, the values are still not sequential, but at least steady. The difference between the two approaches would then be very small.

This one still holds: If you need unique sequential numbers, and you use MySQL, use an auto increment field, they do just that.

查看更多
登录 后发表回答