有什么方法可以在 Java 中生成与 C# 中生成的 UUID 相同的 UUID?

Is there any way to generate a UUID in Java that is identical to that of the one generated in C#?

我正在将 C# 脚本移植到 Spark (Scala) 中,我 运行 遇到了 Scala 中 UUID 生成与 C# 中 GUID 生成的问题。

有什么方法可以在 Java 中生成与在 C# 中生成的 UUID 相同的 UUID?

我通过从字符串的 MD5 哈希创建 Guid 来生成数据库的主键。 最后,我想在 Java/Scala 中生成与 C# 脚本中的 UUID 相匹配的 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# 的结果

Scala 的结果

什么有效:

什么没有:

缺少对字节的操作,还有其他方法可以解决这个问题吗?

TL;DR

如果您希望您的 C# 和 Java 以完全相同的方式运行(并且您对现有的 C# 行为感到满意),您需要手动重新排序 uuid_bytes(即交换一些您确定为乱序的条目)。

此外,您不应使用:

UUID.nameUUIDFromBytes(to_encode.trim().getBytes())

而是使用:

public static String getGuidFromByteArray(byte[] bytes) {
    ByteBuffer bb = ByteBuffer.wrap(bytes);
    long high = bb.getLong();
    long low = bb.getLong();
    UUID uuid = new UUID(high, low);
    return uuid.toString();
}

无耻地从偷来的:)

其他背景

如果你不知道,在处理 C# 时 GUIDs:

Note that the order of bytes in the returned byte array is different from the string representation of a Guid value. The order of the beginning four-byte group and the next two two-byte groups is reversed, whereas the order of the last two-byte group and the closing six-byte group is the same. The example provides an illustration.

And:

The order of hexadecimal strings returned by the ToString method depends on whether the computer architecture is little-endian or big-endian.

在您的 C# 中,而不是使用:

Console.WriteLine("Guid: {0}", guid);

您可能要考虑使用:

Console.WriteLine(BitConverter.ToString(guid.ToByteArray()));

您现有的代码在幕后调用 ToString。唉,ToStringToByteArray 不 return same order.

中的字节