UUID与c#代码互操作

c#donet可以为以下java代码生成相同的UUID吗? 如果是这样的话? 我试过GUID但没有用!

文本:

String cleartext = "CN=CompanyName;mac=some mac;@host=somehost;email=admin@somedomain.com;issued=01/01/20013;expire=12/12/2013"; 

Java代码:

 UUID uuid = UUID.nameUUIDFromBytes(cleartext.getBytes("UTF-8")); 

C#代码:

 byte[] b = System.Text.Encoding.UTF8.GetBytes(cleartext); Guid uid = new Guid(b); Console.Write(uid.ToString()); 

REF 早先的讨论

如果您只需要相同的UUID字符串(而不是实际的UUID / Guid对象),则此C#方法将返回与Java的UUID.nameUUIDFromBytes(byte[])方法相同的值。

 public static string NameUUIDFromBytes(byte[] input) { MD5 md5 = MD5.Create(); byte[] hash = md5.ComputeHash(input); hash[6] &= 0x0f; hash[6] |= 0x30; hash[8] &= 0x3f; hash[8] |= 0x80; string hex = BitConverter.ToString(hash).Replace("-", string.Empty).ToLower(); return hex.Insert(8, "-").Insert(13, "-").Insert(18, "-").Insert(23, "-"); } 

C#示例

 string test = "test"; Console.Out.WriteLine(NameUUIDFromBytes(Encoding.UTF8.GetBytes(test))); Output: 098f6bcd-4621-3373-8ade-4e832627b4f6 

Java示例

 UUID test = UUID.nameUUIDFromBytes("test".getBytes("UTF-8")); System.out.println(test); Output: 098f6bcd-4621-3373-8ade-4e832627b4f6 

编辑 :我知道它是在事后,但这将产生一个具有相同值的实际Guid对象。 只是因为任何人都想要它。

 public static Guid NameGuidFromBytes(byte[] input) { MD5 md5 = MD5.Create(); byte[] hash = md5.ComputeHash(input); hash[6] &= 0x0f; hash[6] |= 0x30; hash[8] &= 0x3f; hash[8] |= 0x80; byte temp = hash[6]; hash[6] = hash[7]; hash[7] = temp; temp = hash[4]; hash[4] = hash[5]; hash[5] = temp; temp = hash[0]; hash[0] = hash[3]; hash[3] = temp; temp = hash[1]; hash[1] = hash[2]; hash[2] = temp; return new Guid(hash); } 

这段代码绝对不适用于.NET。

Guid(Byte[])构造函数必须 占用16个字节 (因为Guids是128位),否则它将抛出ArgumentException。 你的字符串超过16个字节。

但是,据说,C#和Java 仍然不会使用传递给构造函数的相同16个字节生成相同的UUID。 在Java中,您可以将任意数量的字节传递到UUID构造函数中,它将创建这些字节的哈希值。 换一种说法:

在C#中:

 Guid g = new Guid(new Byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}); Console.WriteLine(g); 

会产生不同的价值:

 UUID u = UUID.nameUUIDFromBytes(new byte[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}); System.out.println(u); 

……用Java。

您可以在Java中实现.NET的Byte[16]构造函数,或者在.NET中实现Java的哈希构造函数,但我建议在两个平台上使用UUID的字符串表示,例如, "190c4c10-5786-3212-9d85-018939108a6c"

如果您尝试从字符串创建哈希 ,则可能需要检查MD5类。 你想要的东西是这样的:

 var md5 = System.Security.Cryptography.MD5.Create(); byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(cleartext); byte[] hashBytes = md5.ComputeHash(inputBytes); 

MD5是一种标准算法,它将为.NET和Java中的相同字符串生成相同的哈希值。

如果您希望互操作性不依赖于您无法控制的代码。 它可能会随着每个Java版本或实现而改变。

你可以采取使用的方式

 /** * Static factory to retrieve a type 3 (name based) {@code UUID} based on * the specified byte array. * * @param name * A byte array to be used to construct a {@code UUID} * * @return A {@code UUID} generated from the specified array */ public static UUID nameUUIDFromBytes(byte[] name) { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException nsae) { throw new InternalError("MD5 not supported"); } byte[] md5Bytes = md.digest(name); md5Bytes[6] &= 0x0f; /* clear version */ md5Bytes[6] |= 0x30; /* set to version 3 */ md5Bytes[8] &= 0x3f; /* clear variant */ md5Bytes[8] |= 0x80; /* set to IETF variant */ return new UUID(md5Bytes); } 

资源

并将其复制到您的代码中。 在其他语言中完全创建它,你的问题应该消失。

如果“类型3(基于名称)UUID”是精确指定结果的标准,则可以跳过在Java中复制它,因为实现永远不会返回不同的结果。 您可能会找到其他语言的实现,而不需要手动移植它。