I want to create a token generator that generates tokens that cannot be guessed by the user and that are still unique (to be used for password resets and confirmation codes).
I often see this code; does it make sense?
md5(uniqid(rand(), true));
According to a comment uniqid($prefix, $moreEntopy = true)
yields
first 8 hex chars = Unixtime, last 5 hex chars = microseconds.
I don't know how the $prefix
-parameter is handled..
So if you don't set the $moreEntopy flag to true, it gives a predictable outcome.
QUESTION: But if we use uniqid
with $moreEntopy
, what does hashing it with md5 buy us? Is it better than:
md5(mt_rand())
edit1: I will store this token in an database column with a unique index, so I will detect columns. Might be of interest/
I know the question is old, but it shows up in Google, so...
As others said,
rand()
,mt_rand()
oruniqid()
will not guarantee you uniqueness... evenopenssl_random_pseudo_bytes()
should not be used, since it uses deprecated features of OpenSSL.What you should use to generate random hash (same as md5) is random_bytes() (introduced in PHP7). To generate hash with same length as MD5:
bin2hex(random_bytes(16));
If you are using PHP 5.x you can get this function by including random_compat library.
First, the scope of this kind of procedure is to create a key/hash/code, that will be unique for one given database. It is impossible to create something unique for the whole world at a given moment. That being said, you should create a plain, visible string, using a custom alphabet, and checking the created code against your database (table). If that string is unique, then you apply a
md5()
to it and that can't be guessed by anyone or any script. I know that if you dig deep into the theory of cryptographic generation you can find a lot of explanation about this kind of code generation, but when you put it to real usage it's really not that complicated.Here's the code I use to generate a simple 10 digit unique code.
And here are some generated codes, although you can run it yourself to see it work:
SpQ0T0tyO%
Uwn[MU][.
D|[ROt+Cd@
O6I|w38TRe
Of course, there can be a lot of "improvements" that can be applied to it, to make it more "complicated", but if you apply a
md5()
to this, it'll become, let's say "unguessable" . :)