What you can say about the code presented is that every century the chances of collision will be greater because it is cutting the first two numbers for the year.
The date()
function formats the date and time ( 2016-12-11 08:54:20 ), resulting in this: 20161211085420
Next removes the first two numbers, thus: 161211085420
Here we have a small problem because when you reach the year 2116, in 100 years, you will have more chances of collisions even shuffling randomly with letters from A to G (ABCDEFG), which, incidentally, is little to ensure greater combinations. Of course, it's ridiculous to worry about that, but since you asked where there was going to be a problem. Basically you should think about obvious collision chances.
In your example, you generated this: e1d6e1c2e1g1g0f8f5f4a2a0
and it is very easy to understand the sequence just by removing the letters.
You can argue that 100 years is a long time, nobody here will be alive and probably the system you are creating and will not be used, plus it will be used for user registration and not for generating large amounts of IDs at the same time. But even under that justification it's still creating something that does not mask the sequence very well. Anyone with no programming knowledge can understand the sequence and that it is a date.
If we are to point out a "problem" and as the intention seems to be masking the sequence, I believe it is relevant to put this into the agenda.
In this context, I will focus on sequence masking. So the question I ask is, why not use the timestamp value itself?
And if you still want to "shuffle" you can only convert to letters.
I usually use this:
$id = microtime();
$a = explode(' ', $id);
$a[0] = str_replace('.', '', $a[0]);
$a[0] = base_convert($a[0], 10, 36);
$a[1] = base_convert($a[1], 10, 36);
echo $id.' -> '.$a[0].$a[1];
Returns something like this: 0.70350700 1481537805 -> 15vuy4oi2hvx
This first, 0.70350700 1481537805
, is the value returned from the microtime()
function.
Remove the dot character (.), separate the two numbers and convert each with base_convert ().
070350700 -> 15vuy4
1481537805 -> oi2hvx
At the end, the converted result is concatenated, resulting in this ID: 15vuy4oi2hvx
It is half the space that would occupy with what it presented in the question: e1d6e1c2e1g1g0f8f5f4a2a0
and still a little more "efficient" in relation to collisions for concatenating the microtime to the timestamp besides the fact of not worrying about the date, unless that the environment where you run has a wrong date configured for a value in the past whose dates already have generated codes. These are ridiculous possibilities, but it's possible.
Comparing the runtime,
Question script: 0.0000128746032714844
Script from above example: 0.0000109672546386719
It is not so relevant, so the biggest advantage is the final string that would occupy half of the space.
In general, there is no problem whatsoever in what you presented in the question, given the conditions. But I thought it would be helpful to demonstrate another logic that I believe is a bit better for generating a more economical string.