一个UUID生成算法的C语言实现 --- WIN32版本 .

时间:2023-12-25 19:13:07
一个UUID生成算法的C语言实现——WIN32版本
cheungmine
2007-9-16
根据定义,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个字符,不包括结尾空字符’/0’。所以,要想容纳一个UUID字符串,必须声明为一个char[36+1]的字符数组。
以软件算法实现UUID非常有现实意义。参考RFC4122文档和其他一些开源代码,我写了一个WIN32下的UUID实现C语言程序——UUID32.c。程序符合RFC4122标准。程序不但实现创建UUID和UUID String,还可以对UUID进行字符和时间上的比较。还可以从UUID从提取时间戳(精度到秒)。头文件uuid32.h定义如下:
];
} 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 */

       其中,头文件"cdatatype.h"如下:
/* cdatatype.h 
   2008-09-15 Last created by cheungmine.
   All rights reserved by cheungmine.
*/
#ifndef CDATATYPE_H__
#define CDATATYPE_H__

/*============================================================================*/
typedef unsigned char uchar, byte, BYTE;

typedef unsigned short uint16, word_t, ushort;

typedef unsigned int uint, uint32, dword_t, size_t;

typedef unsigned long ulong;

typedef __int64 int64;
typedef unsigned __int64 uint64, qword_t;

#ifndef BOOL
    #define BOOL  int
    #define TRUE  1
    #define FALSE 0
#endif

#ifndef RESULT
    #define RESULT  long
    #define SUCCESS        0
    #define ERROR        -1
#endif

#define SIZE_BYTE    1
#define SIZE_SHORT    2
#define SIZE_INT    4
#define SIZE_FLT    4
#define SIZE_DBL    8
#define SIZE_WORD    2
#define SIZE_DWORD    4
#define SIZE_QWORD    8
#define SIZE_LINT    8
#define SIZE_INT64    8
#define SIZE_UUID    16

/*============================================================================*/
#endif    /*CDATATYPE_H__*/

MD5算法生成的文件有:md5.h和md5.c,分别罗列如下:

], MD5_CTX *);

char* MD5_sign (const unsigned char *str, unsigned int len);

#endif    /* _MD5_H__ */

);
    }
}

uuid32.c文件如下:

;
}

好了,到此,所有文件都列出来了,它们是:cdatatype.h、md5.h、uuid32.h、md5.c和uuid32.c。

最后是测试代码:

;
}

以上代码保证正确。请放心使用!