我遇到了一个问题,需要为一个字符串生成GUID - 例如:
Guid g = New Guid("Mehar");
如何计算"Mehar"的GUID?我一直遇到异常。
我遇到了一个问题,需要为一个字符串生成GUID - 例如:
Guid g = New Guid("Mehar");
如何计算"Mehar"的GUID?我一直遇到异常。
虽然这个帖子很老,但我们是这样解决这个问题的:
由于 .NET框架中的Guid是任意的16字节(或者说128位),所以你可以通过将任意字符串应用任何生成16字节哈希的哈希函数来计算Guid,并随后将结果传递给Guid构造函数。
我们决定使用MD5哈希函数,示例代码可能如下:
string input = "asdfasdf";
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
Guid result = new Guid(hash);
}
请注意,这个GUID生成方法本身有一些缺陷,因为它依赖于散列函数的质量!如果你使用的字符串产生相同的散列值,它将会影响你的软件行为。以下是产生128位数字摘要的最流行的哈希函数列表:
xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx
,其中**3
**表示Type 3
,y掩码为10xx
。您还可以使用SHA1哈希(Type 5),其中将3更改为5。 - Ian BoydGuid
的哈希算法的信息外,符合某些位(例如 Type 3 Guid)的重要性是什么?这些信息在比较中扮演什么角色? - BaltoStarEncoding
(最好是 Encoding.UTF8
),而不是 Encoding.Default
。 - CodeAngrynew Guid(String s)
重载是为了能够从典型的Guid字符串表示中创建Guid,例如"00000000-0000-0000-0000-000000000000"。uuid.uuid4()
生成一个随机的UUID。
uuid.uuid5(namespace, name)
基于命名空间标识符(也是 UUID)和名称(字符串)的 SHA-1 哈希值生成一个 UUID。
因此,如果您需要一个字符串的 ID 作为对象,而不是值的 ID,则应使用给定的字符串对您的私有 UUID 进行混淆,您的私有 UUID 可以使用 uuid1
仅生成一次,然后将其用作 uuid3
或 uuid5
的命名空间。
这些变量和版本在维基百科上有描述:Universally_unique_identifier#Variants_and_versions
这里是我的方法,如果可能的话,我故意使用字符串转十六进制转储-至少可以看到字符串有多大,如果需要-使用一些在线十六进制转换器进行解码。但是,如果字符串太长(超过16个字节)-则使用sha-1计算哈希并从中生成guid。
/// <summary>
/// Generates Guid based on String. Key assumption for this algorithm is that name is unique (across where it it's being used)
/// and if name byte length is less than 16 - it will be fetched directly into guid, if over 16 bytes - then we compute sha-1
/// hash from string and then pass it to guid.
/// </summary>
/// <param name="name">Unique name which is unique across where this guid will be used.</param>
/// <returns>For example "{706C7567-696E-7300-0000-000000000000}" for "plugins"</returns>
static public String GenerateGuid(String name)
{
byte[] buf = Encoding.UTF8.GetBytes(name);
byte[] guid = new byte[16];
if (buf.Length < 16)
{
Array.Copy(buf, guid, buf.Length);
}
else
{
using (SHA1 sha1 = SHA1.Create())
{
byte[] hash = sha1.ComputeHash(buf);
// Hash is 20 bytes, but we need 16. We loose some of "uniqueness", but I doubt it will be fatal
Array.Copy(hash, guid, 16);
}
}
// Don't use Guid constructor, it tends to swap bytes. We want to preserve original string as hex dump.
String guidS = "{" + String.Format("{0:X2}{1:X2}{2:X2}{3:X2}-{4:X2}{5:X2}-{6:X2}{7:X2}-{8:X2}{9:X2}-{10:X2}{11:X2}{12:X2}{13:X2}{14:X2}{15:X2}",
guid[0], guid[1], guid[2], guid[3], guid[4], guid[5], guid[6], guid[7], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]) + "}";
return guidS;
}
https://dev59.com/s3E85IYBdhLWcg3wtV_1#5657517
这里有一个基于RFC 4122 §4.3的github代码片段,它可以通过一个字符串和命名空间创建一个Guid(你可以选择自己的命名空间来确保不受外部环境的干扰)。
代码片段的直接链接: https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs
SHA256 sHA256 = SHA256.Create();
var byte32hash = sHA256.ComputeHash(Encoding.UTF8.GetBytes("myphrase"));
var guid = BitConverter.ToString(byte32hash.Take(16).ToArray()).Replace("-", "").ToLower();
var id = Guid.Parse(guid);
Guid是随机的,它们并不固有地分配给任何字符串或其他值。
如果您需要这样的链接,请将guid存储在字典中,并在创建新的guid之前首先检查是否存在该guid。
Guid(string)
接收一个格式为{00000000-0000-0000-0000-000000000000}
的GUID字符串。 - Rubens Farias