青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-167  評論-8  文章-0  trackbacks-0
一個UUID生成算法的C語言實現(xiàn)——WIN32版本
 
cheungmine
2007-9-16
 
根據(jù)定義,UUID(Universally Unique IDentifier,也稱GUID)在時間和空間都是唯一的。為保證空間的唯一性,每個UUID使用了一個48位的值來記錄,一般是計算機的網(wǎng)卡地址。為保證時間上的唯一性,每個UUID具有一個60位的時間戳(timestamp)。這個時間戳表示自公元1582年(絕對不是1852,這是《COM技術(shù)內(nèi)幕》,1999年3月第1版第89頁中的一個錯誤)10月15號00:00:00:00以來的時間,是以100納秒為單位的時間間隔。1納秒(ns)=10-9秒(s)。UUID算法可以保證至大約公元3400年仍然唯一。UUID的C語言結(jié)構(gòu)定義如下:
 
typedef struct _uuid_t
{
     unsigned long      data1;       
     unsigned short     data2;
     unsigned short     data3;
     unsigned char      data4[8];
} uuid_t;
 
它的結(jié)構(gòu)大小為16個字節(jié)。即sizeof(uuid_t)==16為TRUE。寫成16進制字符串的格式,一般為:
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 
上面的字符串形式,占用36個字符,不包括結(jié)尾空字符’\0’。所以,要想容納一個UUID字符串,必須聲明為一個char[36+1]的字符數(shù)組。
 
以軟件算法實現(xiàn)UUID非常有現(xiàn)實意義。參考RFC4122文檔和其他一些開源代碼,我寫了一個WIN32下的UUID實現(xiàn)C語言程序——UUID32.c。程序符合RFC4122標(biāo)準(zhǔn)。程序不但實現(xiàn)創(chuàng)建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 */
 
  
       其中,頭文件"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,分別羅列如下:

#ifndef _MD5_H__
#define _MD5_H__
/* MD5.H - header file for MD5C.C */

/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD5 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.

   2007-09-15 Last modified by cheungmine.
 
*/

/* MD5 context. */
typedef 
struct {
    unsigned 
int state[4];                /* state (ABCD) */
    unsigned 
int count[2];                /* number of bits, modulo 2^64 (lsb first) */
    unsigned 
char buffer[64];    /* input buffer */
} MD5_CTX;

void  MD5_init (MD5_CTX *);
void  MD5_update (MD5_CTX *const unsigned char *str, unsigned int len);
void  MD5_fini (unsigned char[16], MD5_CTX *);

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

#endif    /* _MD5_H__ */
/* 
 * md5.c - Copyright 1997 Lachlan Roche 
 *       - Modified by cheungmine, 2007-9-15
 
*/

#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>
#include 
<memory.h>
#include 
"md5.h"

#define MD5STR_LEN        32    


/*=====================================================================
   The remaining code is the reference MD5 code (md5c.c) from rfc1321
   MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm

   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
   rights reserved.

   License to copy and use this software is granted provided that it
   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
   Algorithm" in all material mentioning or referencing this software
   or this function.

   License is also granted to make and use derivative works provided
   that such works are identified as "derived from the RSA Data
   Security, Inc. MD5 Message-Digest Algorithm" in all material
   mentioning or referencing the derived work.

   RSA Data Security, Inc. makes no representations concerning either
   the merchantability of this software or the suitability of this
   software for any particular purpose. It is provided "as is"
   without express or implied warranty of any kind.

   These notices must be retained in any copies of any part of this
   documentation and/or software.
=====================================================================
*/

/* Constants for _MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21

static void _MD5Transform(unsigned int[4], const unsigned char[64]);
static void _Encode(unsigned char *, unsigned int *, unsigned int);
static void _Decode(unsigned int *const unsigned char *, unsigned int);

static unsigned char PADDING[64= {
    
0x80000000000000000000000,
    
00000000000000000000000,
    
0000000000000000000
};

/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))

/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
   Rotation is separate from addition to prevent recomputation. 
*/
#define FF(a, b, c, d, x, s, ac) { 
 (a) 
+= F ((b), (c), (d)) + (x) + (unsigned int)(ac); 
 (a) 
= ROTATE_LEFT ((a), (s)); 
 (a) 
+= (b); 
  }
#define GG(a, b, c, d, x, s, ac) { 
 (a) 
+= G ((b), (c), (d)) + (x) + (unsigned int)(ac); 
 (a) 
= ROTATE_LEFT ((a), (s)); 
 (a) 
+= (b); 
  }
#define HH(a, b, c, d, x, s, ac) { 
 (a) 
+= H ((b), (c), (d)) + (x) + (unsigned int)(ac); 
 (a) 
= ROTATE_LEFT ((a), (s)); 
 (a) 
+= (b); 
  }
#define II(a, b, c, d, x, s, ac) { 
 (a) 
+= I ((b), (c), (d)) + (x) + (unsigned int)(ac); 
 (a) 
= ROTATE_LEFT ((a), (s)); 
 (a) 
+= (b); 
  }

/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void MD5_init(MD5_CTX * context)
{
    context
->count[0= context->count[1= 0;
    
/* Load magic initialization constants. */
    context
->state[0= 0x67452301;
    context
->state[1= 0xefcdab89;
    context
->state[2= 0x98badcfe;
    context
->state[3= 0x10325476;
}

/* MD5 block update operation. Continues an MD5 message-digest operation, 
   processing another message block, and updating the context. 
*/
void MD5_update(MD5_CTX * context, const unsigned char *input, unsigned int inputLen)
{
    unsigned 
int i, index, partLen;

    
/* Compute number of bytes mod 64 */
    index 
= (unsigned int) ((context->count[0>> 3& 0x3F);

    
/* Update number of bits */
    
if ((context->count[0+= ((unsigned int) inputLen << 3)) < ((unsigned int) inputLen << 3))
        context
->count[1]++;
    context
->count[1+= ((unsigned int) inputLen >> 29);

    partLen 
= 64 - index;

    
/* Transform as many times as possible. */
    
if (inputLen >= partLen) {
        memcpy((
void *&context->buffer[index], (void *) input, partLen);
        _MD5Transform(context
->state, context->buffer);

        
for (i = partLen; i + 63 < inputLen; i += 64)
            _MD5Transform(context
->state, &input[i]);

        index 
= 0;
    }
    
else
        i 
= 0;

    
/* Buffer remaining input */
    memcpy((
void *&context->buffer[index], (void *&input[i], inputLen - i);
}

/* MD5 finalization. Ends an MD5 message-digest operation, writing the message digest and zeroizing the context. */
void MD5_fini(unsigned char digest[16], MD5_CTX * context)
{
    unsigned 
char bits[8];
    unsigned 
int index, padLen;

    
/* Save number of bits */
    _Encode(bits, context
->count, 8);

    
/* Pad out to 56 mod 64. */
    index 
= (unsigned int) ((context->count[0>> 3& 0x3f);
    padLen 
= (index < 56? (56 - index) : (120 - index);
    MD5_update(context, PADDING, padLen);

    
/* Append length (before padding) */
    MD5_update(context, bits, 
8);

    
/* Store state in digest */
    _Encode(digest, context
->state, 16);

    
/* Zeroize sensitive information.*/
    memset((
void *) context, 0sizeof (*context));
}

#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )

char* MD5_sign (const unsigned char *str, unsigned int len)
{
    
int i;
    MD5_CTX     md5;
    
static char md5_str[MD5STR_LEN+1];
    
char hash[16], tmp[3];
    md5_str[
0= 0;
            
    MD5_init(
&md5);
    MD5_update (
&md5, str, len);
    MD5_fini (hash, 
&md5);
        
    
for ( i = 0 ; i < 16 ; i++ )
    {
        _itoa((unsigned 
char)hash[i], tmp , 16);

        
if (tmp[1== 0){
            tmp[
2]=0;    tmp[1]=tmp[0]; tmp[0]='0';
        }
        strcat(md5_str, tmp);
    }

    
return md5_str;
}

#pragma warning(pop)    /* C4996 */

/* MD5 basic transformation. Transforms state based on block. */
static void _MD5Transform(unsigned int state[4], const unsigned char block[64])
{
    unsigned 
int a = state[0], 
                 b 
= state[1], 
                 c 
= state[2], 
                 d 
= state[3], 
                 x[
16];

    _Decode(x, block, 
64);

    
/* Round 1 */
    FF(a, b, c, d, x[
0], S11, 0xd76aa478);    /* 1 */
    FF(d, a, b, c, x[
1], S12, 0xe8c7b756);    /* 2 */
    FF(c, d, a, b, x[
2], S13, 0x242070db);    /* 3 */
    FF(b, c, d, a, x[
3], S14, 0xc1bdceee);    /* 4 */
    FF(a, b, c, d, x[
4], S11, 0xf57c0faf);    /* 5 */
    FF(d, a, b, c, x[
5], S12, 0x4787c62a);    /* 6 */
    FF(c, d, a, b, x[
6], S13, 0xa8304613);    /* 7 */
    FF(b, c, d, a, x[
7], S14, 0xfd469501);    /* 8 */
    FF(a, b, c, d, x[
8], S11, 0x698098d8);    /* 9 */
    FF(d, a, b, c, x[
9], S12, 0x8b44f7af);    /* 10 */
    FF(c, d, a, b, x[
10], S13, 0xffff5bb1);    /* 11 */
    FF(b, c, d, a, x[
11], S14, 0x895cd7be);    /* 12 */
    FF(a, b, c, d, x[
12], S11, 0x6b901122);    /* 13 */
    FF(d, a, b, c, x[
13], S12, 0xfd987193);    /* 14 */
    FF(c, d, a, b, x[
14], S13, 0xa679438e);    /* 15 */
    FF(b, c, d, a, x[
15], S14, 0x49b40821);    /* 16 */

    
/* Round 2 */
    GG(a, b, c, d, x[
1], S21, 0xf61e2562);    /* 17 */
    GG(d, a, b, c, x[
6], S22, 0xc040b340);    /* 18 */
    GG(c, d, a, b, x[
11], S23, 0x265e5a51);    /* 19 */
    GG(b, c, d, a, x[
0], S24, 0xe9b6c7aa);    /* 20 */
    GG(a, b, c, d, x[
5], S21, 0xd62f105d);    /* 21 */
    GG(d, a, b, c, x[
10], S22, 0x2441453);    /* 22 */
    GG(c, d, a, b, x[
15], S23, 0xd8a1e681);    /* 23 */
    GG(b, c, d, a, x[
4], S24, 0xe7d3fbc8);    /* 24 */
    GG(a, b, c, d, x[
9], S21, 0x21e1cde6);    /* 25 */
    GG(d, a, b, c, x[
14], S22, 0xc33707d6);    /* 26 */
    GG(c, d, a, b, x[
3], S23, 0xf4d50d87);    /* 27 */
    GG(b, c, d, a, x[
8], S24, 0x455a14ed);    /* 28 */
    GG(a, b, c, d, x[
13], S21, 0xa9e3e905);    /* 29 */
    GG(d, a, b, c, x[
2], S22, 0xfcefa3f8);    /* 30 */
    GG(c, d, a, b, x[
7], S23, 0x676f02d9);    /* 31 */
    GG(b, c, d, a, x[
12], S24, 0x8d2a4c8a);    /* 32 */

    
/* Round 3 */
    HH(a, b, c, d, x[
5], S31, 0xfffa3942);    /* 33 */
    HH(d, a, b, c, x[
8], S32, 0x8771f681);    /* 34 */
    HH(c, d, a, b, x[
11], S33, 0x6d9d6122);    /* 35 */
    HH(b, c, d, a, x[
14], S34, 0xfde5380c);    /* 36 */
    HH(a, b, c, d, x[
1], S31, 0xa4beea44);    /* 37 */
    HH(d, a, b, c, x[
4], S32, 0x4bdecfa9);    /* 38 */
    HH(c, d, a, b, x[
7], S33, 0xf6bb4b60);    /* 39 */
    HH(b, c, d, a, x[
10], S34, 0xbebfbc70);    /* 40 */
    HH(a, b, c, d, x[
13], S31, 0x289b7ec6);    /* 41 */
    HH(d, a, b, c, x[
0], S32, 0xeaa127fa);    /* 42 */
    HH(c, d, a, b, x[
3], S33, 0xd4ef3085);    /* 43 */
    HH(b, c, d, a, x[
6], S34, 0x4881d05);    /* 44 */
    HH(a, b, c, d, x[
9], S31, 0xd9d4d039);    /* 45 */
    HH(d, a, b, c, x[
12], S32, 0xe6db99e5);    /* 46 */
    HH(c, d, a, b, x[
15], S33, 0x1fa27cf8);    /* 47 */
    HH(b, c, d, a, x[
2], S34, 0xc4ac5665);    /* 48 */

    
/* Round 4 */
    II(a, b, c, d, x[
0], S41, 0xf4292244);    /* 49 */
    II(d, a, b, c, x[
7], S42, 0x432aff97);    /* 50 */
    II(c, d, a, b, x[
14], S43, 0xab9423a7);    /* 51 */
    II(b, c, d, a, x[
5], S44, 0xfc93a039);    /* 52 */
    II(a, b, c, d, x[
12], S41, 0x655b59c3);    /* 53 */
    II(d, a, b, c, x[
3], S42, 0x8f0ccc92);    /* 54 */
    II(c, d, a, b, x[
10], S43, 0xffeff47d);    /* 55 */
    II(b, c, d, a, x[
1], S44, 0x85845dd1);    /* 56 */
    II(a, b, c, d, x[
8], S41, 0x6fa87e4f);    /* 57 */
    II(d, a, b, c, x[
15], S42, 0xfe2ce6e0);    /* 58 */
    II(c, d, a, b, x[
6], S43, 0xa3014314);    /* 59 */
    II(b, c, d, a, x[
13], S44, 0x4e0811a1);    /* 60 */
    II(a, b, c, d, x[
4], S41, 0xf7537e82);    /* 61 */
    II(d, a, b, c, x[
11], S42, 0xbd3af235);    /* 62 */
    II(c, d, a, b, x[
2], S43, 0x2ad7d2bb);    /* 63 */
    II(b, c, d, a, x[
9], S44, 0xeb86d391);    /* 64 */

    state[
0+= a;
    state[
1+= b;
    state[
2+= c;
    state[
3+= d;

    
/* Zeroize sensitive information. */
    memset((
void *) x, 0sizeof (x));
}

/* Encodes input (unsigned int) into output (unsigned char). Assumes len is a multiple of 4. */
static void _Encode(unsigned char *output, unsigned int *input, unsigned int len)
{
    unsigned 
int i, j;

    
for (i = 0, j = 0; j < len; i++, j += 4) {
        output[j] 
= (unsigned char) (input[i] & 0xff);
        output[j 
+ 1= (unsigned char) ((input[i] >> 8& 0xff);
        output[j 
+ 2= (unsigned char) ((input[i] >> 16& 0xff);
        output[j 
+ 3= (unsigned char) ((input[i] >> 24& 0xff);
    }
}

/* Decodes input (unsigned char) into output (unsigned int). Assumes len is a multiple of 4.*/
static void _Decode(unsigned int *output, const unsigned char *input, unsigned int len)
{
    unsigned 
int i, j;

    
for (i = 0, j = 0; j < len; i++, j += 4) {
        output[i] 
= ((unsigned int) input[j]) | (((unsigned int) input[j + 1]) << 8|
                    (((unsigned 
int) input[j + 2]) << 16| (((unsigned int) input[j + 3]) << 24);
    }
}

        uuid32.c文件如下:

/* uuid32.c 
   2007-09-15 Last created by cheungmine.
   Partly rights reserved by cheungmine.
*/

#include 
<stdio.h>
#include 
<string.h>

#include 
<time.h>
#include 
<sys/types.h>
#include 
<sys/timeb.h>

#include 
"uuid32.h"
#include 
"md5.h"


#define MD5_LEN            16
#define UUID_LEN        36

/* microsecond per second. 1s=1000000us=1000000000ns*/
#define NSec100_Per_Sec        10000000
#define USec_Per_Sec        1000000
#define USec_Per_MSec        1000
#define NSec_Since_1582        ((uint64)(0x01B21DD213814000))


/*========================================================================================
                            Private Functions
========================================================================================
*/
static BOOL isbigendian()
{
    
int c = 1;
    
return ( *((unsigned char *&c) == 1 )? FALSE: TRUE;
};

static void swap_word( int size_bytes, void * ptr_word )
{
    
int        i;
    unsigned 
char       temp;
    
for( i=0; i < size_bytes/2; i++ )
    {
        temp 
= ((unsigned char *) ptr_word)[i];
        ((unsigned 
char *) ptr_word)[i] = ((unsigned char *) ptr_word)[size_bytes-i-1];
        ((unsigned 
char *) ptr_word)[size_bytes-i-1= temp;
    }
};

static void write_word( unsigned char* stream, word_t val )
{
    memcpy(stream, 
&val, 2);
    
if( isbigendian() ) swap_word( 2, stream );
};

static void write_dword( unsigned char* stream, dword_t val )
{
    memcpy(stream, 
&val, 4);
    
if( isbigendian() ) swap_word( 4, stream );
};

static void  read_word( const unsigned char* stream, word_t* val )
{
    memcpy( val, stream, 
2 );
    
if( isbigendian() )    swap_word( 2, val );
};

static void  read_dword( const unsigned char* stream, dword_t* val )
{
    memcpy( val, stream, 
4 );
    
if( isbigendian() )    swap_word( 4, val );
};

static BOOL is_xdigit(char c)
{
    
/* isxdigit returns a non-zero value if c is a hexadecimal digit (A – F, a – f, or 0 – 9). */
    
return ((c>='A'&&c<='F')||(c>='a'&&c<='f')||(c>='0'&&c<='9'))? TRUE : FALSE;
};


/* make a pseudorandom numbel based on current time*/
static int pseudo_rand()
{
#ifdef _USE_32BIT_TIME_T
    assert(
0);
#endif

    
struct _timeb  timebuf;

#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )
    _ftime64(
&timebuf);
#pragma warning(pop)    /* C4996 */
    
    srand((uint32) ((((uint32)timebuf.time
&0xFFFF)+(uint32)timebuf.millitm)^(uint32)timebuf.millitm));

    
return rand();
};


/*========================================================================================
                            Public Functions
========================================================================================
*/

BOOL is_uuid_string(
const char *uuid) 
{    
    
static const char fmt[] = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    
int i;
    assert(uuid 
!= NULL);
    
for (i = 0; i < sizeof(fmt); i++)
        
if (fmt[i] == 'x')
            
if (!is_xdigit(uuid[i]))
                
return FALSE;
        
else if (uuid[i] != fmt[i])
            
return FALSE;

    
return TRUE;
}


/**
 * internal
 * ingroup uuid
 * The thread synchronization lock used to guarantee UUID uniqueness
 * for all the threads running within a process.
 
*/
void uuid_create(uuid_t* u) 
{    
    
static BOOL        initialized = FALSE;
    
static int64    timestamp;
    
static uint32    advance;
    
static uint16    clockseq;
    
static uint16    node_high;
    
static uint32    node_low;
    int64            time;    
/* unit of 100ns */
    uint16            nowseq;
    
int                r;

    #ifdef _USE_32BIT_TIME_T
        assert(
0);
    
#endif

    
struct _timeb  tv;

    assert(u);

#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )
    _ftime64(
&tv);
#pragma warning(pop)    /* C4996 */

    
/* time is counter of 100ns time interval since Oct.15, 1582 (NOT 1852) */
    time 
= ((uint64) tv.time) * USec_Per_Sec + ((uint64) tv.millitm*USec_Per_MSec);
    time 
= time * 10 + NSec_Since_1582;

    
if (!initialized) 
    {
        timestamp 
= time;
        advance 
= 0;

        r 
= pseudo_rand();

        clockseq 
= r >> 16;
        node_high 
= r | 0x0100;
        
        node_low 
= pseudo_rand();
        
        initialized 
= TRUE;
    } 
    
else if (time < timestamp) 
    {
        timestamp 
= time;
        advance 
= 0;
        clockseq
++;
    } 
    
else if (time == timestamp) 
    {
        advance
++;
        time 
+= advance;
    } 
    
else 
    {
        timestamp 
= time;
        advance 
= 0;
    }
    nowseq 
= clockseq;

    assert(u);
    u
->data1 = (dword_t) time;
    u
->data2 = (word_t) ((time >> 32& 0xffff);
    u
->data3 = (word_t) (((time >> 48& 0x0ffff| 0x1000);
    write_word(
&(u->data4[6]), (word_t) ((nowseq & 0x3fff| 0x8000));    
    write_word(
&(u->data4[4]), (word_t) (node_high));                    
    write_dword(
&(u->data4[0]), (dword_t) (node_low));            
}

/**
 * internal
 * ingroup uuid
 * The thread synchronization lock used to guarantee UUID uniqueness
 * for all the threads running within a process.
 
*/
char *uuid_create_string(void
{
    uuid_t  u;
    uuid_create(
&u);
    
return uuid_to_string(&u);
}

char *uuid_to_string(const uuid_t*  u)
{
    
static char uuid_str[UUID_LEN+1];
    
ushort a,b;
    uint32  c;
    read_word(
&(u->data4[6]), &a);
    read_word(
&(u->data4[4]), &b);
    read_dword(
&(u->data4[0]), &c);

#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )
    sprintf(uuid_str, 
"%08lx-%04x-%04x-%04x-%04x%08lx"
                u
->data1,
                u
->data2,
                u
->data3,
                a, b, c);
#pragma warning(pop)    /* C4996 */
    
return uuid_str;
}

/**
 * internal
 * ingroup uuid
 * The predefined namespace UUID. Expressed in binary format
 * to avoid unnecessary conversion when generating name based UUIDs.
 
*/
static const unsigned char namespace_uuid[] = {
        
0x9c0xfb0xd90x1f0x110x720x4a0xf6,
        
0xbd0xcb0x9f0x340xe40x6f0xa00xfb
};

void  uuid_create_external(const char *external, uuid_t* u) 
{
    MD5_CTX md5;
    unsigned 
char uuid[16];    
    
    assert(external 
!= NULL);

    MD5_init(
&md5);
    MD5_update(
&md5, namespace_uuid, sizeof(namespace_uuid));
    MD5_update(
&md5, (unsigned char *) external, (unsigned int) strlen(external));
    MD5_fini(uuid, 
&md5);

    u
->data1 = (dword_t) (uuid[0<< 24 | uuid[1<< 16 | uuid[2<< 8 | uuid[3]);
    u
->data2 = (word_t)  (uuid[4<< 8 | uuid[5]);
    u
->data3 = (word_t)  (((uuid[6& 0x0f| 0x30<< 8 | uuid[7]);    
    
    
/* BYTE 6-7 */
    write_word(
&(u->data4[6]), (word_t) (((uuid[8& 0x3f| 0x80<< 8 | uuid[9]));        
    
/* BYTE 4-5 */
    write_word(
&(u->data4[4]), (word_t) (uuid[10<< 8 | uuid[11]));                        
    
/* BYTE 0-3 */
    write_dword(
&(u->data4[0]), (dword_t) (uuid[12<< 24 | uuid[13<< 16 | uuid[14<< 8 | uuid[15]));
}

/**
 * Get timestamp from a UUID
 *
*/
void uuid_to_timestamp(const uuid_t* u, timestamp_t* t)
{
    int64   time, t2, t3;
    
struct  tm*  p;
    assert(u);

    t2 
= u->data2;
    t3 
= u->data3;

    time 
= u->data1 + (t2<<32+ ((t3&0x0fff)<<48);        /* 100ns */
    time 
-= NSec_Since_1582;

    t
->tm_fraction = (long)(time%NSec100_Per_Sec);
    
    time 
/= 10;
    time 
/= USec_Per_Sec; 
    
#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )
    p 
= _localtime64(&time);
#pragma warning(pop)    /* C4996 */
    
    t
->tm_hour = p->tm_hour;
    t
->tm_mday = p->tm_mday;
    t
->tm_min = p->tm_min;
    t
->tm_mon = p->tm_mon;
    t
->tm_sec = p->tm_sec;
    t
->tm_wday = p->tm_wday;
    t
->tm_yday = p->tm_yday;
    t
->tm_year = p->tm_year;
}

char* timestamp_to_string(const timestamp_t* time)
{
    
struct tm t;
    t.tm_hour 
= time->tm_hour;
    t.tm_mday 
= time->tm_mday;
    t.tm_min 
= time->tm_min;
    t.tm_mon 
= time->tm_mon;
    t.tm_sec 
= time->tm_sec;
    t.tm_wday 
= time->tm_wday;
    t.tm_yday 
= time->tm_yday;
    t.tm_year 
= time->tm_year;

#pragma warning(push)    /* C4996 */
#pragma warning( disable : 4996 )
    
return asctime(&t);
#pragma warning(pop)    /* C4996 */
}



/**
 * 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)
{
    
int i;

#define CHECK_COMP(f1, f2)  if ((f1) != (f2)) return ((f1) < (f2) ? -1 : 1);
    
    CHECK_COMP(u1
->data1, u2->data1);
    CHECK_COMP(u1
->data2, u2->data2);
    CHECK_COMP(u1
->data3, u2->data3);

    
for(i=0; i<8; i++)
        CHECK_COMP(u1
->data4[i], u1->data4[i]);

#undef CHECK_COMP

    
return 0;
}

/**
 * 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)
{    
#define CHECK_COMP(f1, f2)  if ((f1) != (f2)) return ((f1) < (f2) ? -1 : 1);
    
    CHECK_COMP(u1
->data1, u2->data1);
    CHECK_COMP(u1
->data2, u2->data2);
    CHECK_COMP(u1
->data3, u2->data3);

#undef CHECK_COMP

    
return 0;
}

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

最后是測試代碼:

/* uuidgen.c 
   2007-09-15 Last created by cheungmine.
   All rights reserved by cheungmine.
   C application
*/
#include 
<stdio.h>
#include 
<stdlib.h>
#include 
<string.h>

#include 
"md5.h"
#include 
"uuid32.h"

int main()
{
    
char *sign, *uid;
    uuid_t u, v, x;
    timestamp_t  t;
    
    sign 
= MD5_sign("hello world", (unsigned int)strlen("hello world"));
    printf(
"md5 string digit:%s ", sign);
    
    uuid_create(
&u);
    uid 
= uuid_to_string(&u);
    printf(
"uuid U to string:{%s} ", uid);

    uuid_create(
&v);
    uid 
= uuid_to_string(&v);
    printf(
"uuid V to string:{%s} ", uid);
    
    printf(
"uuid compare U with V lexically:%d ", uuid_compare(&u, &v));

    printf(
"uuid compare V with U temporally:%d ", uuid_compare_time(&v, &u));


    uid 
= uuid_create_string();
    printf(
"new uuid string:{%s} ", uid);
        
    uuid_create_external(
"cheungmine"&x);
    uid 
= uuid_to_string(&x);
    printf(
"new external uuid to string:{%s} ", uid);
        
    uuid_to_timestamp(
&u, &t);
    printf(
"%s ", timestamp_to_string(&t));
    
    
return 0;
}
posted on 2011-04-29 15:41 老馬驛站 閱讀(4753) 評論(0)  編輯 收藏 引用 所屬分類: c++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产天堂久久综合网| 国产精品日韩欧美一区| 91久久黄色| 欧美freesex交免费视频| 久久免费视频在线观看| 欧美xx视频| 亚洲欧洲综合| 一本色道久久综合亚洲二区三区 | 亚洲九九精品| 亚洲美女电影在线| 午夜精品免费视频| 免费毛片一区二区三区久久久| 欧美激情一区二区三区在线视频| 亚洲精品欧美| 一区二区三区视频观看| 久久国产一区二区三区| 欧美国产精品劲爆| 国产精品一区二区你懂的| 欧美激情综合色综合啪啪| 美女视频黄免费的久久| 欧美一级片久久久久久久| 久久综合亚洲社区| 亚洲美女电影在线| 久久精品欧美日韩| 欧美日韩 国产精品| 国产一区二区三区在线观看免费视频| 亚洲国产精品va| 亚洲女爱视频在线| 欧美精品成人在线| 韩国三级在线一区| 亚洲欧美日韩精品久久久| 亚洲电影免费观看高清| 先锋影音国产一区| 欧美日韩一区自拍| 亚洲精品美女| 欧美承认网站| 久久精品国产精品亚洲| 国产精品久久久久久久久久ktv| 亚洲高清视频中文字幕| 久久精品成人一区二区三区| av成人国产| 欧美精品久久久久久久久久| 一区二区亚洲精品国产| 久久国产精品亚洲77777| 一本大道av伊人久久综合| 欧美成va人片在线观看| 亚洲第一网站| 美女精品视频一区| 久久久久久久一区二区三区| 国产亚洲高清视频| 欧美一区二区三区啪啪| 亚洲一区二区三区四区中文| 欧美午夜视频网站| 亚洲免费影视| 亚洲女优在线| 国产日韩免费| 久久久久国产一区二区三区四区| 亚洲欧美日韩中文播放| 国产精品久久国产三级国电话系列| 夜夜嗨av一区二区三区中文字幕| 亚洲高清免费在线| 欧美母乳在线| 一区二区三区|亚洲午夜| 亚洲精品乱码久久久久| 欧美久久成人| 亚洲一区美女视频在线观看免费| 日韩一区二区精品| 欧美视频精品一区| 亚洲欧美中文日韩在线| 午夜精品国产更新| 国内自拍视频一区二区三区| 麻豆精品一区二区av白丝在线| 久久久噜噜噜久久人人看| 亚洲国产成人porn| 国产一区二区三区精品欧美日韩一区二区三区 | 国产嫩草一区二区三区在线观看| 亚洲作爱视频| 中日韩高清电影网| 国产精自产拍久久久久久| 久久精品人人做人人爽| 久久亚裔精品欧美| 亚洲精选久久| 玖玖在线精品| 狠狠色2019综合网| 欧美国产日韩亚洲一区| 欧美日韩成人综合| 午夜精品一区二区三区在线| 久久国产主播精品| 日韩一级视频免费观看在线| 亚洲一区二区三区高清 | 免费日韩视频| 欧美日韩综合在线免费观看| 久久精品中文字幕一区二区三区| 六月天综合网| 亚洲欧美日本国产有色| 久久综合九色综合欧美狠狠| 亚洲一区二区三区在线播放| 久久精品夜色噜噜亚洲aⅴ| 在线亚洲国产精品网站| 久久精品女人的天堂av| 亚洲午夜免费福利视频| 玖玖国产精品视频| 欧美影院成人| 欧美风情在线观看| 久久精品亚洲一区二区三区浴池| 欧美精品在线播放| 乱中年女人伦av一区二区| 国产精品久久久久久超碰| 亚洲国产精品ⅴa在线观看| 国产欧美日本一区二区三区| 亚洲青涩在线| 91久久中文| 久久裸体艺术| 久久久久久久久久久一区| 欧美色精品天天在线观看视频| 欧美www视频| 精品999在线播放| 亚洲一区二区三区在线| 一本久久综合亚洲鲁鲁| 麻豆精品在线视频| 久久亚洲高清| 国产亚洲精品一区二555| 在线一区二区日韩| 亚洲小说区图片区| 欧美日韩免费观看中文| 亚洲高清av| 亚洲欧洲另类国产综合| 久久久久久久精| 午夜视频精品| 国产精品国色综合久久| 亚洲一区美女视频在线观看免费| 久久久亚洲国产美女国产盗摄| 亚洲免费观看高清在线观看| 国产精品久久久久av免费| 欧美二区在线观看| 免费永久网站黄欧美| 免费观看成人鲁鲁鲁鲁鲁视频| 一本久久综合亚洲鲁鲁| 亚洲在线日韩| 亚洲精品在线观| 亚洲精品视频在线观看免费| 久久久人人人| 裸体一区二区| 亚洲国产1区| 久久综合久久综合这里只有精品 | 欧美大片91| 亚洲国产精品久久久久婷婷884| 在线成人中文字幕| 久久一区视频| 91久久精品一区二区三区| 夜夜嗨av一区二区三区免费区| 欧美日韩国产页| 亚洲图片欧洲图片日韩av| 久久国产视频网| 好吊日精品视频| 蜜桃av综合| 亚洲靠逼com| 欧美一区二区观看视频| 一区在线观看| 欧美日韩福利视频| 亚洲欧美日韩精品在线| 老鸭窝毛片一区二区三区| 亚洲免费高清| 国产日韩欧美在线播放| 免费国产自线拍一欧美视频| 在线视频一区二区| 欧美a级片一区| 亚洲欧美精品伊人久久| 一区二区三区中文在线观看| 欧美日韩一区三区四区| 欧美专区18| 亚洲美女精品久久| 久久免费高清视频| 亚洲天堂男人| 在线观看不卡av| 欧美午夜视频| 牛牛影视久久网| 午夜免费电影一区在线观看| 亚洲国产精品一区二区尤物区 | 欧美电影在线| 亚洲欧美在线x视频| 亚洲第一页中文字幕| 久久成人18免费网站| 亚洲精品久久久蜜桃| 欧美成人精品1314www| 亚洲图片激情小说| 久久久999精品视频| 夜色激情一区二区| 激情欧美一区二区三区| 欧美日韩精品免费观看| 久久激情五月激情| 亚洲视频二区| 亚洲区一区二区三区| 久久综合伊人77777| 午夜免费电影一区在线观看| 亚洲精品日韩欧美| 在线电影欧美日韩一区二区私密| 国产精品狠色婷| 欧美三级视频| 欧美日韩国产精品一卡|