5 ms·
For a toy project, I'm currently using a 64-bit integer of which the first bit is a sign bit (I'm using Postgres' bigint), the next 32-bits make a UNIX epoch ti
by Confiks 9y ago
For a toy project, I'm currently using a 64-bit integer of which the first bit is a sign bit (I'm using Postgres' bigint), the next 32-bits make a UNIX epoch timestamp in seconds, and the rest of the 31 bits make a random number. In this way, the ID is very easily sortable by time, although it's a bit of a gimmick.
The scheme allows for 2 billion possible records per second, although if you consider birthday collisions, it comes down to a lot less (but I could re-insert on duplicates). I could later also use some of the random bits to inscribe extra data into the ID.
The bits from the two halves are then interspersed to make sure the first half looks random, and transformed to a 11-character id, for example /^[0-9A-Za-z]{11}$/. I can reject some IDs beforehand if they match a list of bad strings. The result is receiving an id such as "Vxe61yU5Cci" or "WgOUBEO88gb".
- mort96 9y agoWhat happens in 2038? I hope you're never representing those 32 bits of UNIX timestamp as a signed integer anywhere. If you're making sure to always keep it unsigned, what happens in year 2106? EDIT: I'm not criticizing you, and a valid counter argument would be that you make absolutely sure to always store the timestamp unsigned, that it doesn't need to work until 2106 because it's a toy project, or that an overflow wouldn't really matter because you make sure to keep it unique even after an overflow, but I get scared any time storing a UNIX timestamp in 32 bits is mentioned, and am wondering if you've considered it.
- bpicolo 9y ago> but I get scared any time storing a UNIX timestamp in 32 bits is mentioned You're scared because an average app hasn't considered a problem that's 21 years off? Seems like a premature worry
- random023987 9y ago> You're scared because an average app hasn't considered a problem that's 21 years off? Seems like a premature worry 'Those who cannot remember the past are condemned to repeat it.'. --George Santayana
- bpicolo 9y agoYeah? Did people need to prepare for the y2k bug in 1979?
- mort96 9y agoWell yeah, weren't a lot of the broken systems big cobol systems from that era? You never know what software ends up being still used for critical systems 20 years down the road, so it's stupid to knowingly make a new system which is guaranteed to break in 20 years. That said, it sounds like this guy has thought about it, and is making sure to use all 32 bits to store the timestamp.
- deleted 9y ago[deleted]
- Confiks 9y agoThe literal Elixir code is: def epoched_random_uid, do: epoched_random_uid(&:erlang.system_time/1, &:crypto.strong_rand_bytes/1) def epoched_random_uid(system_time, strong_rand_bytes) do time = system_time.(:second) randint = strong_rand_bytes.(4) |> :crypto.bytes_to_integer bor(time <<< 31, randint >>> 1) end So it uses – or at least I hope it does; you may file a bug report – a full 32 bits for the time, but it leaves the sign bit to be zero. I didn't want to deal with negative uids in PostgreSQL (bigint), but they actually would be perfectly valid. The sign bit could be used to expand the timestamp another bit. You could argue that the "2038 problem" (31 effective bits) in the context of a uid scheme of an application that is bootstrapped today, is actually the "2084 problem", because the wraparound to timestamps in 1970 could be construed as being from 2018.
- deleted 9y ago[deleted]