Welcome

首页 / 软件开发 / 数据结构与算法 / C语言实现UUID生成算法(WIN32版本)

C语言实现UUID生成算法(WIN32版本)2010-10-29 csdn 张亮根据定义,UUID(Universally Unique IDentifier,也称GUID)在时间和空间都是唯一的。为保证空间的唯一性,每个UUID使用了一个48位的值来记录,一般是计算机的网卡地址。为保证时间上的唯一性,每个UUID具有一个60位的时间戳(timestamp)。这个时间戳表示自公元1582年(绝对不是1852,这是《COM技术内幕》,1999年3月第1版第89页中的一个错误)10月15号00:00:00:00以来的时间,是以100纳秒为单位的时间间隔。1纳秒(ns)=10-9秒(s)。UUID可以保证至大约公元3400年仍然唯一。UUID的C语言结构定义如下:

typedef struct _uuid_t
{
unsigned long data1;
unsigned short data2;
unsigned short data3;
unsigned char data4[8];
} uuid_t;

它的结构大小为16个字节。即sizeof(uuid_t)==16为TRUE。写成16进制字符串的格式,一般为:

"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

上面的字符串形式,占用36个字符,不包括结尾空字符’’。所以,要想容纳一个UUID字符串,必须声明为一个char[36+1]的字符数组。

以软件算法实现UUID非常有现实意义。参考RFC4122文档和其他一些开源代码,我写了一个WIN32下的UUID实现C语言程序——UUID32.c。程序符合RFC4122标准。程序不但实现创建UUID和UUID String,还可以对UUID进行字符和时间上的比较。还可以从UUID从提取时间戳(精度到秒)。头文件uuid32.h定义如下:

/* uuid32.h
2007-09-15 Last created by cheungmine.
Partly rights reserved by cheungmine.
*/
#ifndef UUID32_H_INCLUDED
#define UUID32_H_INCLUDED

#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <memory.h>

#include "cdatatype.h"

typedef struct _timestamp_t
{
BYTE tm_sec; /* Seconds after minute (0 – 59). */
BYTE tm_min; /* Minutes after hour (0 – 59). */
BYTE tm_hour; /* Hours after midnight (0 – 23). */
BYTE tm_mday; /* Day of month (1 – 31). */
BYTE tm_mon; /* Month (0 – 11; January = 0). */
BYTE tm_wday; /* Day of week (0 – 6; Sunday = 0). */
short tm_year; /* Year (current year minus 1900). */
short tm_yday; /* Day of year (0 – 365; January 1 = 0). */
long tm_fraction; /* Fraction little than 1 second */
} timestamp_t;

typedef struct _uuid_t
{
unsigned long data1;
unsigned short data2;
unsigned short data3;
unsigned char data4[8];
} uuid_t;


/**
* Checks whether the given string matches the UUID format.
* params:
* [in] uuid - the potential UUID string
* return
* TRUE if the given string is a UUID, FALSE otherwise
**/
BOOL is_uuid_string(const char *uuid);

/**
* Generates a new UUID. The UUID is a time-based time 1 UUID.
* A random per-process node identifier is used to avoid keeping global
* state and maintaining inter-process synchronization.
**/
void uuid_create(uuid_t* uuid);

/**
* Generates a new UUID string. The returned UUID is a time-based time 1 UUID.
* A random per-process node identifier is used to avoid keeping global
* state and maintaining inter-process synchronization.
* return UUID string (newly allocated)
**/
char *uuid_create_string(void);

/**
* Generates a name-based (type 3) UUID string from the given external
* identifier. The special namespace UUID is used as the namespace of
* the generated UUID.
* params
* [in] external - the external identifier
* return
* UUID string (newly allocated)
**/
void uuid_create_external(const char *external, uuid_t* uuid);

/**
* Translate a uuid_t to a uuid string
* return UUID string
**/
char *uuid_to_string(const uuid_t* uuid);

/**
* Get timestamp from a UUID
**/
void uuid_to_timestamp(const uuid_t* uuid, timestamp_t* time);


/**
* Resurn a description of timestamp NOT including fraction
**/
char* timestamp_to_string(const timestamp_t* time);

/**
* Compare two UUID"s lexically
* return
* -1 u1 is lexically before u2
* 0 u1 is equal to u2
* 1 u1 is lexically after u2
*/
int uuid_compare(const uuid_t *u1, const uuid_t *u2);

/**
* Compare two UUID"s temporally
* return
* -1 u1 is temporally before u2
* 0 u1 is equal to u2
* 1 u1 is temporally after u2
*/
int uuid_compare_time(const uuid_t *u1, const uuid_t *u2);


#endif /* UUID32_H_INCLUDED */