76

I was wondering what the easiest way to convert a UUID to a unique integer would be? I have tried using the hash code but people tell me that it is not going to always be unique if i use the hash code?

So what is the easiest way? Is the hash code unique?

H.B.
  • 166,899
  • 29
  • 327
  • 400
Alex Hope O'Connor
  • 9,354
  • 22
  • 69
  • 112
  • 2
    No, it's not - by definition. Also, if it were unique, why then would anybody need UUIDs? – Ingo Apr 06 '11 at 08:35
  • Define unique. Globally, or just within your application, or a bit of code? – Bart van Heukelom Apr 06 '11 at 08:36
  • Its just that by some silly specification I needed an application unique integer, I wanted to make use of the UUID class, but it turns out I cannot down scale it. – Alex Hope O'Connor Apr 06 '11 at 08:58
  • 4
    It would be easier if you asked the real question: how can I have an application unique integer ? could I convert a UUID to it ? Then we could answer your problem and not just tell you you can't use UUID for that purpose... – pgras Apr 06 '11 at 09:04

6 Answers6

47

You are going to have a problem since the UUID is 128 bits and the int is only 32bit. You'll either have to accept the risk of collisions and try to fudge it to a smaller space (hashCode is probably a good way to do that) or find an alternative (use the UUID directly, map to a BigInteger - difficult to tell without knowing why)

Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
18

Answering the How can I have a unique application wide Integer:

If it needs to be unique even after restarts or if you application is clustered you may use a Database sequence.

If it just needs to be unique during the runtime use a static AtomicInteger.

EDIT (example added):

public class Sequence {

  private static final AtomicInteger counter = new AtomicInteger();

  public static int nextValue() {
    return counter.getAndIncrement();
  }
}

Usage:

int nextValue = Sequence.nextValue();

This is thread safe (different threads will always receive distinct values, and no values will be "lost")

ememorais
  • 329
  • 2
  • 11
pgras
  • 12,614
  • 4
  • 38
  • 46
8

A UUID is a 16-Byte number (128 bit). You can't crunch it into an int (32 bit) while preserving it's uniqueness.

Mathematically spoken: 296 UUIDs will share the same Java-int-size hash value (which is ... a lot ;) )

A way out - some real life UUID often have a rather static part. So in isolated scenarios, the real unique portion of UUIDs may be less then 32 bit.

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
6

We had a requirement to convert all our UUIDs into serial numbers. Finally, we tested and used the next algorithm:

  1. Get CRC64 of uuid(16 bytes) using the ECMA polynomial 0xC96C5795D7870F42. Do not use ISO polynomial because it could cause a lot of collisions for some UUID generation algorithms.

  2. Now we have crc64(8 bytes). Take the first N bytes(in our case 5 in yours it will be 4 bytes for int and all bytes for int64)

We tested this method and it works well for several million UUIDs.

Our additional step: convert 5 bytes number into a number with base 36 and finally we have SN: 4YD3SOJB.

Hodza
  • 3,118
  • 26
  • 20
  • Great! But is any library out there for CRC64 using a special polynominal? Iam using Python and there is a CRC64ISO which I guess is not what you meant. Event a C lib is good since I can use ffi for calling it. – Kamyar Aug 25 '21 at 18:50
3

No, the hash code is not (and cannot be) unique. The thing with a GUID/UUID is that you need all 128 bits to guarantee uniqueness, therefore scaling it down in any way will give problems, see e.g. GUIDs are globally unique, but substrings of GUIDs aren't.

Honestly, I think you're better off with just using sequential integers and skip the GUID thing altogether. If you need GUIDs for any reason, then use them and don't try generating an integer from them.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • 6
    Comments: 1) The hash code might be unique. You don't know. [Don't rely on it though](http://security.stackexchange.com/a/52881/94827). 2) You don't have a guarantee of UUID uniqueness. Just a very good probability of never seeing a collision. 3) Even if you did "scaling it down in any way", you don't necessarily create any problems. You increase the risk of collisions, yes, and you need to be aware of the consequences of breaking the UUID standard, but that may be perfectly fine in some situations. 4) The link is dead. – Zero3 Jan 11 '16 at 09:26
-3

You may convert uuid to BigInteger and keep it unique.

              BigInteger  big = new BigInteger(uuid, 16);