Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate unique positive Long using UUID

Tags:

java

uuid

I have a requirement to generate unique Long ids for my database primary key column.

I thought i can use UUID.randomUUID().getMostSignificantBits() but sometimes its generating some negative long also which is problem for me.

Is it possible to generate only positive long from UUID ?There will be like billions of entries so i want that each generated key must be unique.

like image 460
Saurabh Kumar Avatar asked Mar 03 '13 10:03

Saurabh Kumar


People also ask

How does UUID generate time based?

To generate time based UUIDs in maven project you have add the dependency of Generator that is generate time based UUIDs. If you have a normal java project you have to import library of Generator java-uuid-generator. Then generate the UUID: UUID uuid= Generators.

Can UUID have special characters?

UUID generates special characters? No. A UUID is actually a 128-bit value, not text.

Is Hashcode of UUID unique?

No, the hash code is not (and cannot be) unique.


3 Answers

UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE

The reason why this works is, when you do bitwise & with 1 it allows the same digit to pass as it is and when you do bitwise & with 0 it blocks it and result is 0. Now, Long.MAX_Value in binary is

0111111111111111111111111111111111111111111111111111111111111111 

this is 0 followed by 63 1s (total is 64 bits, it's long in java)

So when you bitwise & a number X with this above number then you will get the same number X except that the leftmost bit is now turned into a zero. Which means you've only changed the sign of that number and not the value.

like image 68
Sasha Pechenyi Avatar answered Oct 13 '22 01:10

Sasha Pechenyi


As the others have written, long does not have enough space for a unique number. But in many cases a number may be unique enough for a specific use. For example, a timestamp with the nanosecond precision is often good enough. To get it, shift the current milliseconds 20 bits left to allocate space for nanoseconds and then overlay it with the nanoseconds:

(System.currentTimeMillis() << 20) | (System.nanoTime() & ~9223372036854251520L);

The nano & ~9223372036854251520L part takes the current nanoseconds and sets the first 44 bytes to 0, leaving only the right 20 bits which represent nanoseconds up to one millisecond (999999 nanos) It is the same as:

nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000

Side note: nanoseconds should not be used to represent the current time because their starting point is not fixed in time and because they are recycled when they reach the maximum.

You can use any other bit manipulation. It is usually good to take into account the current time and something else such as the current thread id, process id, ip.

like image 22
Daniel Nuriyev Avatar answered Oct 13 '22 01:10

Daniel Nuriyev


Take a look at http://commons.apache.org/sandbox/commons-id//index.html It has a LongGenerator that can give you exactly what you need.

In addition if you are using Hibernate then you can ask it to generate IDs for you (it has several algorithms you can choose from), in if not you can just take a look at their implementation for example http://grepcode.com/file/repo1.maven.org/maven2/hibernate/hibernate/2.1.8/net/sf/hibernate/id/TableHiLoGenerator.java#TableHiLoGenerator)

like image 8
Doron Manor Avatar answered Oct 13 '22 01:10

Doron Manor