Reputation: 709
I am having a problem generating a GUID for a string - for example:
Guid g = New Guid("Mehar");
How can I compute a GUID for "Mehar"
? I am getting an exception.
Upvotes: 68
Views: 98648
Reputation: 1
You can make guid from phrase word, here is how:
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);
Upvotes: 0
Reputation: 2828
Quite old this thread but this is how we solved this problem:
Since Guid's from the .NET framework are arbitrary 16bytes, or respectively 128bits, you can calculate a Guid from arbitrary strings by applying any hash function to the string that generates a 16 byte hash and subsequently pass the result into the Guid constructor.
We decided to use the MD5 hash function and an example code could look like this:
string input = "asdfasdf";
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
Guid result = new Guid(hash);
}
Please note that this Guid generation has a few flaws by itself as it depends on the quality of the hash function! If your hash function generates equal hashes for lots of string you use, it's going to impact the behaviour of your software.
Here is a list of the most popular hash functions that produce a digest of 128bit:
Please note that one can use also other hash functions that produce larger digests and simply truncate those. Therefore it may be smart to use a newer hash function. To list some:
Today (Aug 2013) the 160bit SHA1 hash can be considered being a good choice.
Upvotes: 151
Reputation: 5243
Here is my own approach, I'm intentionally using String to hex dump if possible - visually it can be seen at least how big string is, and if needed - decoded using some online hex converter. But if string is too long (more than 16 bytes) - then using sha-1 to compute hash and generate guid from it.
/// <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;
}
Upvotes: 4
Reputation: 13231
If op's intent is to create a UUID (Guid) from a string hash of some sort (MD5, SHA-1, et.c.), I found this very similar question with this great answer:
https://stackoverflow.com/a/5657517/430885
It has a link to a github-snippet based on RFC 4122 §4.3, that will create a Guid from a string and a namespace (which you can choose for yourself to guarantee against collisions from outside environments).
Direct link to the snippet: https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/GuidUtility.cs
Upvotes: 3
Reputation: 6423
In general there are few ways to make an universally unique ID (UUID RFC 4122, a.k.a. GUID). We could borrow these four from Python, and make in C# something alike:
uuid.uuid1([node[, clock_seq]])
Generate a UUID from a host ID, sequence number, and the current time. If node is not given, getnode() is used to obtain the hardware address. If clock_seq is given, it is used as the sequence number; otherwise a random 14-bit sequence number is chosen.
uuid.uuid3(namespace, name)
Generate a UUID based on the MD5 hash of a namespace identifier (which is a UUID) and a name (which is a string).
uuid.uuid4()
Generate a random UUID.
uuid.uuid5(namespace, name)
Generate a UUID based on the SHA-1 hash of a namespace identifier (which is a UUID) and a name (which is a string).
So if you need ID of a string as an object, not ID of a value, you should mangle your private UUID with given string,
Your private UUID generate once using uuid1
, and then use it as namespace for uuid3
or uuid5
.
These variants and versions described on Wikipedia Universally_unique_identifier#Variants_and_versions
Upvotes: 4
Reputation: 12573
What you are looking for is probably generating version 3 or version 5 UUIDs, which are name based UUIDs. (version 5 is the recommended). I don't think that the .NET framework has build in support for it. See http://en.wikipedia.org/wiki/Universally_Unique_Identifier
I did a few google searches to see if I could find something in the Win32 API, but nothing came up. However, I am sure that the .NET framework has some implementation hidden somewhere, because as far as I know, when generating a COM object in .NET, and you don't supply an explicit GUID, then the .NET framework generates a name based UUID to create a well-defined ClassID and InterfaceID, i.e. UUIDs that don't change every time you recompile (like VB6). But this is probably hidden, so I guess you need to implement the algorithm yourself. Luckily, .NET provides both an MD5 and SHA1 algorithm so I don't think implementing a version3 and version5 UUID should be too difficult.
Upvotes: 7
Reputation: 138127
You cannot use GUID that way. The constructor of Guid expects a valid, string representation of a Guid.
What you're looking for is called a Hash function. (for example: MD5)
Upvotes: 4
Reputation: 55152
I'm fairly sure you've confused System.Guid
with wanting a hash (say, SHA-256) of a given string.
Note that, when selecting a cryptographically-secure hashing algorithm, MD5, SHA0 and SHA1 are all generally considered dead. SHA2 and up are still usable.
Upvotes: 18
Reputation: 622
Guids are random, they are not intrinsically assigned to any string or other value.
If you need such linking, store the guids in a Dictionary and check for an existing guid first before creating a new one.
Upvotes: -2
Reputation: 102538
I think you have a misunderstanding of what a Guid actually is. There is no Guid representation of a string such as "Mehar".
The reason there is a new Guid(String s)
overload is so that you can create a guid from a typical string representation of one, such as "00000000-0000-0000-0000-000000000000".
See the wiki article for more information on what a Guid actually is.
http://en.wikipedia.org/wiki/Globally_Unique_Identifier
Upvotes: 5