GUID refers to some unique identification number, which can be generated using some algorithm - you can find some descriptions on Microsoft's algorithms - where they try to pick up timestamp, network card number, and on one, and mix up into one unique GUID.
What I have checked - noone prevents you of creating your own "unique" generation algorithm - but you need to somehow ensure that your unique generation algorithm won't collide with existing algorithms, which is highly unlikely. Also GUID's generated by your algorithm should not also collide with your own GUID's.
While browsing internet I have found some approaches to generate such guid - for example - Microsoft Office: http://support.microsoft.com/kb/2186281
When generating GUID from Strings, you can use either String.GetHashCode32 or even calculate for example 20 byte sha-1 hash over string. (First one is easier, but second creates more bytes to use for GUID).
And then start to fill in GUID, as much as it requires it.
Here is some demo code which let's you get to the idea:
using System;
class Program
{
/// <summary>
/// http://stackoverflow.com/questions/53086/can-i-depend-on-the-values-of-gethashcode-to-be-consistent
///
/// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static unsafe int GetHashCode32(string s)
{
fixed (char* str = s.ToCharArray())
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*)chPtr;
for (int i = s.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
}
/// <summary>
/// Generates new product code for particular product / install package.
/// </summary>
/// <param name="productName">Logical product name for which to generate</param>
/// <param name="productVersion">Product version in form "1.0.0"</param>
/// <returns></returns>
static public String GenerateProductCode( String productName, String productVersion )
{
String[] vparts = productVersion.Split(".".ToCharArray());
int[] verParts = new int [3] { 1, 0, 0 };
int i = 0;
foreach( String v in vparts )
{
Int32.TryParse(v, out verParts[i++] );
if( i >= 3 ) break;
}
//
// "MyCompanyName", "1.0.2" will generate guid like this: {F974DC1F-0001-0000-0002-10009CD45A98}
// ^ Hash over manufacturer name - "MyCompanyName"
// ^ Version - "<major>-<minor>-<build>" in hexadecimal
// ^ 1 as for 64 bit.
// ^000 - just reserved for future needs
// ^ Hash over product name
//
// See also similar generation schemes - http://support.microsoft.com/kb/2186281.
//
String newGuid = String.Format("{0:X8}-{1:X4}-{2:X4}-{3:X4}-1000{4:X8}", GetHashCode32("MyCompanyName"), verParts[0], verParts[1], verParts[2], GetHashCode32(productName));
newGuid = "{" + newGuid + "}";
return newGuid;
}
static void Main()
{
String s = GenerateProductCode("MyProduct", "1.0.2");
Console.WriteLine(s);
}
}
Will print out:
{F974DC1F-0001-0000-0002-10003618D1E1}
But in similar manner you can generate GUIDs in C++ as well - use sprintf() most probably.
Here is .NET compatible function for converting String into hash code:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int GetHashCode32( const wchar_t* ps )
{
int num = 0x15051505;
int num2 = num;
const wchar_t* s = ps;
const char* chPtr=(const char*) ps;
size_t numBuff = wcslen((wchar_t*) chPtr) * 2;
int* numPtr = (int*)chPtr;
for (int i = wcslen(s); i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
void GetHash(const wchar_t* p)
{
printf("'%S' = %08X", p, GetHashCode32(p));
printf("\r\n");
}
void main(void)
{
GetHash(L"testing");
GetHash(L"MainClass::" __FUNCTIONW__);
GetHash(L"1");
GetHash(L"");
}