我正在将一份C#脚本移植到Spark(Scala)中,但在Scala中生成UUID与在C#中生成GUID存在问题。
是否有办法在Java中生成与C#中生成的UUID相同的UUID?
我通过从字符串的MD5哈希值创建Guid来生成数据库的主键。最终,我希望能够生成Java / Scala中与C#脚本中相匹配的UUID,以便使用C#实现哈希处理的现有数据无需重新哈希。
需要移植的C#代码:
String ex = "Hello World";
Console.WriteLine("String to Hash: {0}", ex);
byte[] md5 = GetMD5Hash(ex);
Console.WriteLine("Hash: {0}", BitConverter.ToString(md5));
Guid guid = new Guid(md5);
Console.WriteLine("Guid: {0}", guid);
private static byte[] GetMD5Hash(params object[] values) {
using (MD5 md5 = MD5.Create())
return md5.ComputeHash(Encoding.UTF8.GetBytes(s));
}
Scala 移植代码:
val to_encode = "Hello World"
val md5hash = MessageDigest.getInstance("MD5")
.digest(to_encode.trim().getBytes())
val md5string = md5hash.map("%02x-".format(_)).mkString
val uuid_bytes = UUID.nameUUIDFromBytes(to_encode.trim().getBytes())
printf("String to encode: %s\n", to_encode)
printf("MD5: %s\n", md5string)
printf("UUID: %s\n", uuid_bytes.toString)
C#的结果:
- 需要哈希的字符串:Hello World
- MD5: B1-0A-8D-B1-64-E0-75-41-05-B7-A9-9B-E7-2E-3F-E5
- GUID: b18d0ab1-e064-4175-05b7-a99be72e3fe5
Scala的结果:
- 需要哈希的字符串:Hello World
- MD5: b10a8db164e0754105b7a99be72e3fe5
- UUID: b10a8db1-64e0-3541-85b7-a99be72e3fe5
可以匹配的内容:
- MD5哈希(GUID和UUID都是基于此)匹配。
不匹配的内容:
- 前三个字段在C#中的字节序已切换(橙色)
- C#的GUID选择前三个字段(4、2、2)的本机字节顺序,这在这种情况下是小端字节序,并且将最后一个字段(8)设置为大端字节序,而Java的UUID对所有四个字段都使用大端字节顺序;这解释了C#中前三个字段的字节顺序。
- 第四个和第五个字节不同(红色)
- Java在6-7位上交换以表示UUID的版本和变体,这可能解释了第4和第5个字节中的差异。 这似乎是难以克服的障碍。
- 我知道Java使用有符号字节,而C#使用无符号字节;这也可能相关。
除了操作字节,还有其他修复此问题的方法吗?
UUID.nameUUIDFromBytes(to_encode.trim().getBytes())
吗?在C#示例中,您使用哈希作为Guid的输入。 - Bernhard Hiller