A Date-Sorted ID (DSID) is a 53-bit number made of three components:
- a 16-bit date.
- a 5-bit extension.
- a 32-bit random number.
DSIDs can be safely used in IEEE-754 floating-point data types, such as Number in Javascript.
Binary structure:
+--------+--------+-----+--------+--------+--------+--------+
| date (16 bits) | ? | random (32 bits) |
+--------+--------+--.--+--------+--------+--------+--------+
`--> extra (5 bits)
date: 2^16 = ~179 years, from 1970 AD to 2149 AD
extra: 2^5 = 32 possible values for customization
random: 2^32 = 4,294,967,296 possible values per day
The date component represents the number of days since January 1, 1970 UTC, which can be calculated by dividing the number of seconds elapsed since January 1, 1970 UTC by 86400, which in turn is the number of seconds in a day.
The random component is a 32-bit number generated by the best PRNG available, ideally a cryptographically secure PRNG.
The extra component is a 5-bit extension that allows customizations, such as:
- an additional random number between 0 and 31 to expand the random component, increasing the randomness of the generated identifier;
- the number of seconds in the current day divided by 32 to extend the date component, splitting the day in slices of 2700 seconds or 42 minutes;
- a number permanently associated with a generator when there is more than one ID generator, for example: a node ID, shard ID, machine ID, instance ID, etc.
Example of a DSID sequence:
2824921106300058
2824921875945230
2824921151321411
2824920409047328
2824922174987757
2824921187162625
2824922217655524
2824921052940409
2824920986704317
2824922337594611
The sequence was generated with this Bash loop:
for i in `seq 10`; do
echo "(($EPOCHSECONDS / 86400) * 2^37) + 0 + ($RANDOM * 2^16) + $RANDOM" | bc;
done;
Python code example:
import time
import random
(int(time.time() / 86400) * 2**37) + 0 + random.randint(0, 2**32-1)
Google AppSheet code example:
NUMBER(TOTALSECONDS(NOW() - DATETIME('1970-01-01')) / 86400) * POWER(2, 32) + 0 + RANDBETWEEN(0, POWER(2, 32) - 1)
In the examples above, the extra component is explicitly set to 0 to indicate that no specific customization was selected.
MIT License