How to generate a GUID in C?

独自空忆成欢 提交于 2019-12-03 18:58:17
paercebal

You can either use or look at the code of Boost.Uuid :

http://www.boost.org/doc/libs/1_47_0/libs/uuid/index.html

It is a C++ library, but still, you can find inside how the code author retrieved the Uuid on multiple systems. Last time I checked (january 2010), I found at least the following implementations for Windows and Linux/Solaris (this info could be outdated):

UUID/GUID on Linux/Solaris

Open a file to /dev/urandom and read enough bytes (16) to make up a GUID/UUID.

UUID/GUID on Windows

Use the following WinAPI functions

Other implementations

The Wikipedia page on GUID/UUID has a list of alternative implementations you could use/study:

https://en.wikipedia.org/wiki/UUID#Implementations

About your conditions

There is a GUID/UUID type which is always random (the version 4), meaning that to be compatible with other GUID/UUID semantics, you should respect that.

Now, you want the GUID/UUID to be ordered in time. The only way to do that without weakening the GUID/UUID randomness would be to prefix the 16-byte GUID/UUID with an unsigned integer (which would make your identifier data 20-bytes, or more, depending on your integer). Just generate a GUID/UUID, and increase the integer.

E Net Arch

One place to look for an answer to creating a GUID that contains many of the elements the author is looking for is in PHP .. http://us3.php.net/uniqid .. In their examples, they discuss how to add server names, database names, and other elements to a GUID.

However, to address the need for a C based GUID function, here is code based on a JavaScript function .. Create GUID / UUID in JavaScript? .. this example uses RegEx to create the GUID.

Below is code that will create a GUID based on the JavaSCript example. I'm sure there are more elegant solutions out there. This is something cobbled together to help give a clean example for others to follow.

srand (clock());
char GUID[40];
int t = 0;
char *szTemp = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
char *szHex = "0123456789ABCDEF-";
int nLen = strlen (szTemp);

for (t=0; t<nLen+1; t++)
{
    int r = rand () % 16;
    char c = ' ';   

    switch (szTemp[t])
    {
        case 'x' : { c = szHex [r]; } break;
        case 'y' : { c = szHex [r & 0x03 | 0x08]; } break;
        case '-' : { c = '-'; } break;
        case '4' : { c = '4'; } break;
    }

    GUID[t] = ( t < nLen ) ? c : 0x00;
}

printf ("%s\r\n", GUID);

Note: strings end with a 0x00 character.

First off, GUIDs aren't random, they are very well defined mathmatically.

As for your problem, put the GUID creation into the database itself as a stored procedure, that way the system is platform independent. Then, make the GUID an auto-incrementing integer prefixed with a database ID. The prefix allows databases to be merged easily. The database ID needs to be unique for each database. If you control each database then it is straightforward to ensure these are unique. Otherwise you may need a lookup system which maps the database IP address (or some other unique identifier) to a unique database ID.

If you don't have stored procedures then create a table with "NextIndex" and "DatabaseID" fields and update them when a new record is added:

read NextIndex and DatabaseID
increment NextIndex
ID = NextIndex + DatabaseID
add new record, setting "GUID" to the ID value
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!