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());
参考文献早先的讨论
发布于 2013-08-02 17:48:41
如果您只需要相同的UUID字符串(而不是实际的UUID/Guid对象),这个C#方法将返回与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);
}
发布于 2013-08-02 16:35:27
这段代码肯定不适用于.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);
...in 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中为相同的字符串生成相同的散列。
发布于 2013-08-02 16:46:06
如果您想要互操作性,就不要依赖于不受您控制的代码。它可以随每个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);
}
来源
把它复制到你的代码中。同样用其他语言创建,你的问题就会消失。
如果"type 3(基于名称) UUID“是精确指定结果的标准,您可以跳过在Java中复制它,因为实现不应该返回不同的结果。您可能也会找到其他语言的实现,而不需要手动移植它。
https://stackoverflow.com/questions/18021808
复制相似问题