Richard Nemeth
Richard Nemeth

Reputation: 1864

How to generate a unique ID which is time-like sortable?

Is there a way to generate a universally unique ID that has always increasing values by the "time" it is generated? We can assume UTC timezone only for this problem.

What I specifically mean with time-like sort-ability is:

from time import sleep

id1 = generate_unique_id()
sleep(1)

id2 = generate_unique_id()
sleep(1)

id3 = generate_uniqueid()

assert id1 < id2
assert id2 < id3

So id1 could be "abcdefgh-ksfn-123", id2 could be "abcdefgh-ksfn-231" etc.

I do not really wish to use UTC timestamps directly as an ID since that does bear a bit of information I wish not to expose to the users with this ID. We can also assume that this ID will be generated concurrently, i.e. there is a chance that time parameters are identical for 2 separate executions (a tiny chance, but it is there), yet the ID should be different.

Does anything like that exist already in Python/3rd party modules? If not what would be the best approach? Is it even possible to generate ID like this?

Upvotes: 4

Views: 5803

Answers (4)

andreykyz
andreykyz

Reputation: 425

You can use UUID v1 or v7 they are time sortable.

UUID version 7 features a time-ordered value field derived from the widely implemented and well known Unix Epoch timestamp source, the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. As well as improved entropy characteristics over versions 1 or 6. Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible.

more information: https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html#name-uuid-version-7

Upvotes: 1

LSerni
LSerni

Reputation: 57418

Yes, there is. You can use uuid and then the uuid1() function provides exactly what you want:

 uuid.uuid1(0, 0)

will supply a UUID type 1, with node ID of 0 and clock sequence of 0. The remaining 60 bits will be a monotonically increasing time sequence, that will be therefore sortable.

You can use a different node ID for each process, if you want (then, the sorting will happen in node order: first all UUIDs of node A, then all UUIDs of node B), or the PID as clock sequence to ensure that no two processes will get the same UUID (in that case, when sorting, the UUIDs will be sorted in time order, then in PID order):

So to speak,

UUID  = NODENODE-NODE-CLOCKCLOCKCLOCKCLOCK-SEQSEQ

Upvotes: 4

pritesh
pritesh

Reputation: 90

I think this should work for you.

import time
# 1600528948.9750373

id1 = int(str(time.time()).replace(".","")) 
# 16005289641753972
id2 = int(str(time.time()).replace(".","")) 
# 16005289668820095

Upvotes: -3

tdyer
tdyer

Reputation: 101

Consider checking out the monotonic time from the time module (https://docs.python.org/3/library/time.html) - it returns a number of fractional seconds from a clock that only increases so you'd get back increasing numbers over time. For example these are the results when I ran the following:

print(time.monotonic()) # 5052906.443107647
time.sleep(1)
print(time.monotonic()) # 5052907.446823377
time.sleep(1)
print(time.monotonic()) # 5052908.448060763

You could then do some condensing of the numbers and maybe tack on some letters if you like to make the IDs more suitable, but this gets you increasing numbers overtime at the very least

Upvotes: 1

Related Questions