Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UUID is same from different strings

Tags:

java

uuid

I have two different strings, but after parsing to UUID it's seem to be same

public static void main(String[] args) {     try {         UUID t1 = UUID.fromString("38e1036d-7527-42a3-98ca-f2f19d3155db");         UUID t2 = UUID.fromString("123438e1036d-7527-42a3-98ca-f2f19d3155db");         System.out.println(t1.toString().equals(t2.toString()));     } catch (Exception e) {         e.printStackTrace();     } } 

Any idea why it is?

like image 337
Viet Avatar asked Dec 08 '16 08:12

Viet


People also ask

Can a UUID be a string?

It's a UUID, stored in a String. The sixteen octets of a UUID are represented as 32 hexadecimal (base 16) digits, displayed in five groups separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 alphanumeric characters and four hyphens - which can be stored in a String just fine.

How do I know if a string is UUID?

So to check if a string is valid UUID we can use this regular expression, // Regular expression to check if string is a valid UUID const regexExp = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi; This matches all the valid UUID since it checks for the above test cases.

Is UUID reversible?

This also means that one can (in theory) guarantee that some two inputs out there can wind up with the same UUID, and as a result, UUIDs are not generally reversible (however, in specific (limited) cases, perhaps they could be made reversible).


2 Answers

"123438e1036d-7527-42a3-98ca-f2f19d3155db"

This is not a UUID. It's a concatenated string of "1234" and a UUID. The problem here is that the parser should have told you this by throwing an exception. Instead it tries its best to actually find the UUID buried somewhere in there.

Once you extract the UUID from your concatenated string, it's identical to the first UUID which is the correct result you're observing.

We can analyze the parser (thanks to @tim-biegeleisen for providing the link):

public static UUID fromString(String name) {     String[] components = name.split("-");     if (components.length != 5)         throw new IllegalArgumentException("Invalid UUID string: "+name);     for (int i=0; i<5; i++)         components[i] = "0x"+components[i];      long mostSigBits = Long.decode(components[0]).longValue();     mostSigBits <<= 16;     mostSigBits |= Long.decode(components[1]).longValue();     mostSigBits <<= 16;     mostSigBits |= Long.decode(components[2]).longValue();      long leastSigBits = Long.decode(components[3]).longValue();     leastSigBits <<= 48;     leastSigBits |= Long.decode(components[4]).longValue();      return new UUID(mostSigBits, leastSigBits); } 

As we can see, there is no validation except for counting the number of groups limited by hyphens. It just takes those groups and then shifts them into positions. You've added extra characters in front of the first group, which is the most significant part. It's parsed and stored first, and then it gets shifted up and again up until it occupies the most significant part. Now, all bits that were farther left than assumed get pushed out of the long limit, hence they're completely ignored.

like image 152
Agent_L Avatar answered Sep 20 '22 09:09

Agent_L


A UUID stores 128 bits of data. If you give it more it can't store them. I am surprised it doesn't give you an error, but not surprised it truncates the higher bits otherwise.

int i = 0x38e1036d; int j = (int) 0x123438e1036dL; i == j; 
like image 41
Peter Lawrey Avatar answered Sep 19 '22 09:09

Peter Lawrey