簡體   English   中英

如何為字符串生成GUID?

[英]How can I generate a GUID for a string?

我在為字符串生成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.Default.GetBytes(input));
    Guid result = new Guid(hash);
}

請注意,這個Guid一代本身有一些缺陷,因為它取決於哈希函數的質量! 如果您的哈希函數為您使用的大量字符串生成相等的哈希值,則會影響您的軟件行為。

以下是產生128位摘要的最流行的哈希函數列表:

  • RIPEMD(碰撞概率:2 ^ 18)
  • MD4(碰撞概率:肯定)
  • MD5(碰撞概率:2 ^ 20.96)

請注意,也可以使用其他散列函數來生成更大的摘要,並簡單地截斷它們。 因此,使用更新的散列函數可能是明智的。 列出一些:

  • SHA-1
  • SHA-2
  • SHA-3

今天(2013年8月)160bit SHA1哈希可以被認為是一個不錯的選擇。

我很確定你把System.Guid與想要一個給定字符串的哈希(比方說, SHA-256 )混淆了。

請注意,在選擇加密安全散列算法時,MD5,SHA0和SHA1通常都被認為是死的 SHA2及以上版本仍可使用。

您正在尋找的可能是生成版本3或版本5 UUID,它們是基於名稱的UUID。 (建議使用版本5)。 我認為.NET框架並不支持它。 請參見http://en.wikipedia.org/wiki/Universally_Unique_Identifier

我做了一些谷歌搜索,看看我是否能在Win32 API中找到一些東西,但沒有任何結果。 但是,我確信.NET框架在某處隱藏了一些實現,因為據我所知,在.NET中生成COM對象時,如果沒有提供顯式GUID,那么.NET框架會生成一個名稱基於UUID創建一個定義良好的ClassID和InterfaceID,即每次重新編譯時都不會改變的UUID(如VB6)。 但這可能是隱藏的,所以我猜你需要自己實現算法。 幸運的是,.NET提供了MD5和SHA1算法,所以我認為實現版本3和版本5 UUID應該太難了。

通常,很少有方法可以制作通用唯一ID(UUID RFC 4122 ,又名GUID)。 我們可以從Python借用這四個,並在C#中使用類似的東西:

uuid.uuid1([node[, clock_seq]])

從主機ID,序列號和當前時間生成UUID。 如果未給出node,則使用getnode()來獲取硬件地址。 如果給出clock_seq,則將其用作序列號; 否則,選擇隨機的14位序列號。

uuid.uuid3(namespace, name)

基於命名空間標識符(UUID)和名稱(字符串)的MD5哈希生成UUID。

uuid.uuid4()

生成隨機UUID。

uuid.uuid5(namespace, name)

基於命名空間標識符(UUID)和名稱(字符串)的SHA-1哈希生成UUID。

因此,如果您需要字符串的ID作為對象,而不是值的ID,您應該使用給定的字符串來uuid1您的私有UUID。您的私有UUID使用uuid1生成一次,然后將其用作uuid3uuid5命名空間。

這些變體和版本在Wikipedia Universally_unique_identifier#Variants_and_versions中描述

你不能這樣使用GUID。 Guid構造函數需要Guid的有效字符串表示。

您正在尋找的是一個哈希函數。 (例如: MD5

我認為你對Guid究竟是什么有誤解。 沒有像“Mehar”這樣的字符串的Guid表示。

有一個new Guid(String s)重載的原因是你可以從一個典型的字符串表示創建一個guid,例如“00000000-0000-0000-0000-000000000000”。

有關Guid實際是什么的更多信息,請參閱wiki文章。

http://en.wikipedia.org/wiki/Globally_Unique_Identifier

如果op的意圖是從某種類型的字符串哈希(MD5,SHA-1,et.c。)創建一個UUID(Guid),我發現這個非常相似的問題有這個很好的答案:

https://stackoverflow.com/a/5657517/430885

它有一個基於RFC4122§4.3的github-snippet的鏈接,它將從字符串和命名空間創建一個Guid(您可以自己選擇它來保證不受來自外部環境的沖突)。

直接鏈接到代碼段: https//github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs

這是我自己的方法,如果可能的話,我有意使用String進行十六進制轉儲 - 在視覺上可以看到至少有多大的字符串,如果需要的話 - 使用一些在線十六進制轉換器進行解碼。 但是如果字符串太長(超過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;
}

Guids是隨機的,它們本身並不分配給任何字符串或其他值。

如果需要這樣的鏈接,請將guid存儲在Dictionary中,並在創建新guid之前先檢查現有的guid。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM