UUID从不同的string是相同的

我有两个不同的string,但parsing到UUID后,它似乎是相同的

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(); } } 

任何想法,为什么?

“123438e1036d-7527-42a3-98ca-f2f19d3155db”

这不是一个UUID。 它是一个连接的“1234”string和一个UUID。 这里的问题是parsing器应该通过抛出一个exception告诉你这个。 相反,它会尽力find埋在那里的UUID。

一旦从连接的string中提取UUID,它就与您正在观察的正确结果的第一个UUID相同。

我们可以分析parsing器(感谢@ tim-biegeleisen提供的链接):

 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); } 

我们可以看到,除了计算由连字符限制的组数外,没有任何validation。 只需要这些团体,然后转移到职位。 您在第一组前面添加了额外的字符,这是最重要的部分。 先parsing并存储,然后再上移,直到占据最重要的部分。 现在,所有比假设更远的位被推出了long限制,因此它们被完全忽略了。

UUID存储128位数据。 如果你给它更多,它不能存储它们。 我很惊讶它不会给你一个错误,但并不感到惊讶,否则截断高位。

 int i = 0x38e1036d; int j = (int) 0x123438e1036dL; i == j; 

第二个组件“7527”的位移将消除对第一个组件“123438e1036d”所作的修改,从而产生相同的UUID。

第一个组件的处理本身是不同的,但是当uuid的第二个组件被移位时,这个效果就会丢失。

这是因为它从右到左进行检查,并且只有32个字符作为UUID,并删除其他。 一旦顺序32个字符被采取,它不关心别人,因为它实现Serializable接口。

 public final class UUID extends Object implements Serializable, Comparable<UUID> 

1234从你的第二个UUID修剪。

这是它的代码,它有更好的帮助

  public static UUID More ...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); } 

这是在2016年6月报告的Java 8中的已知错误: http : //bugs.java.com/bugdatabase/view_bug.do?bug_id=8159339

另见http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8165199(2016年; 8月报道):

4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8是有效的UUID。

4d4d8f-3b3b81-44f3-968d-d1c1a48b4ac8不是(把第一个破折号移动到左边的两个字符)

使用无效的UUID :: fromString()调用UUID代表004d4dbf-3b81-44f3-968d-d1c1a48b4ac8。