UUID generating code

xiaoxiao2021-03-06  38

UUID Reference Implementation / * ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & ** Digital Equipment Corporation, Maynard, Mass . ** to anyone who acknowledges that this file is provided "AS IS" ** without any express or implied warranty: permission to use, copy, ** modify, and distribute this file for any purpose is hereby ** granted without fee, provided that the above copyright notices and ** this notice appears in all source code copies, and that none of ** the names of Open Software Foundation, Inc., Hewlett-Packard ** Company, or Digital Equipment Corporation be used in advertising * * or publicity pertaining to distribution of the software without ** specific, written prior permission. Neither Open Software ** Foundation, Inc., Hewlett-Packard Company, nor Digital Equipment ** Corporation makes any representations about the suitability of ** this software For any purpose. * / #include

#include

typedef unsigned long unsigned32; typedef unsigned short unsigned16; typedef unsigned char unsigned8; typedef unsigned char byte; #define CLOCK_SEQ_LAST 0x3FFF #define RAND_MASK CLOCK_SEQ_LAST typedef struct _uuid_t {unsigned32 time_low; unsigned16 time_mid; unsigned16 time_hi_and_version; unsigned8 clock_seq_hi_and_reserved; unsigned8 clock_seq_low; byte node [ 6];} uuid_t; typedef struct _unsigned64_t {unsigned32 lo; unsigned32 hi;} unsigned64_t; / * ** Add two unsigned 64-bit long integers * / #define ADD_64b_2_64b (A, B, sum) / {/ if (.! (((A) -> LO & 0x80000000UL) ^ ((b) -> Lo & 0x80000000UL)) {/ f (((a) -> LO & 0x80000000UL) {/ (sum) -> LO = (a) - > LO (B) -> LO; / (SUM) -> Hi = (a) -> Hi (b) -> Hi 1; /} / else {/ (sum) -> LO = (a) -> LO (B) -> LO; / (sum) -> Hi = (a) -> Hi (b) -> hi; /} /} / else {/ (sum) -> LO = (a ) -> LO (b) -> lo; / (sum) -> hi = (a) -> hi (b) -> hi; / if (! (sum) -> lo & 0x80000000 uL) (SUM) -> Hi ; /} /} / * ** Add a 16-bit unsigned integer to a 64-bit unsigned integer. * / #define a DD_16B_2_64B (A, B, SUM) / {/ (Sum) -> Hi = (b) -> Hi; / IF ((b) -> LO & 0x80000000UL) {/ (sum) -> LO = (* a) (B) -> lo; / if (! (Sum) -> lo & 0x80000000ul) (SUM) -> Hi ; /} / else / (sum) -> LO = (* a) (b) . -> lo; /} / * ** Global variables * / static unsigned64_t time_last; static unsigned16 clock_seq; static void mult32 (unsigned32 u, unsigned32 v, unsigned64_t * result) {/ * Following the notation in Knuth, Vol 2.. * / unsigned32 uuid1, uuid2, v1, v2, temp; uuid1 = u >> 16; uuid2 = u & 0xfff; v1 = v >> 16; v2 =

V & 0xfff; Temp = uuid2 * v2; result-> lo = temp & 0xfff; temp = uuid1 * v2 (TEMP >> 16); result-> hi = Temp >> 16; Temp = uuid2 * v1 (Temp & 0xffff); Result-> LO = (Temp & 0xFFFF) << 16; Result-> Hi = UUID1 * V1 (TEMP >> 16);} static void get_system_time (unsigned64_t * uuid_time) {struct timeval tp; unsigned64_t utc, usecs, os_basetime_diff; gettimeofday (& tp, (struct timezone *) 0); mult32 ((long) tp.tv_sec, 10000000, & utc); mult32 ((long) tp.tv_usec, 10, & usecs); ADD_64b_2_64b (& usecs , & utc, & utc);. / * Offset between UUID formatted times and Unix formatted times * UUID UTC base time is October 15, 1582. * Unix base time is January 1, 1970. * / os_basetime_diff.lo = 0x13814000; os_basetime_diff.hi = 0x01B21DD2; ADD_64b_2_64b (& utc, & os_basetime_diff, uuid_time);.} / * ** See "The Multiple Prime Random Number Generator" by Alexander ** Hass pp 368-381, ACM Transactions on Mathematical Software, ** 12/87 *. / static unsigned32 rand_m; static unsigned32 rand_ia; static unsigned32 rand_ib; static unsigned32 rand_irand; static void true_random_init (void) {unsigned64_t t; unsigned16 seed; / * Generating our 'seed' value Start with the current time, but, * since the resolution of clocks is system hardware dependent and * most likely coarser than our Resolution (10 Usec) We 'Mixup' The * bits by xor '

ing all the bits together. This will have the effect * of involving all of the bits in the determination of the seed * value while remaining system independent. Then for good measure * to ensure a unique seed when there are multiple processes * creating UUIDs on A system, we add in the pid. * / rand_m = 971; rand_ia = 11113; rand_ib = 104322; rand_irand = 4181; Get_System_time (& T); SEED = T.LO & 0xFFFF; SEED ^ = (T.LO >> 16 ) & 0xffff; seed ^ = t.hi & 0xfff; seed ^ = (t.hi >> 16) & 0xfff; rand_irand = seed getpid ();} static unsigned16 true_random (void) {ix (((RAND_M = 7)> = 9973) RAND_M - = 9871; IF ((RAND_IA = 1907)> = 99991) Rand_ia - = 89989; IF ((RAND_IB = 73939)> = 224729) RAND_IB - = 96233; rand_irand = (rand_irand * rand_m) rand_ia rand_ib; return (rand_irand >> 16) ^ (rand_irand & RAND_MASK);} / * ** Startup initialization routine for the UUID module * / void uuid_init (void) {true_random_init ();. get_system_time (& time_last) ; #ifdef nonvolatile_clock clock_seq = read_clock ); #else clock_seq = true_random (); #ENDIF} static int Time_cmp (unsigned64_t * Time1, unsigned64_t * Time2) {if (Time1-> Hi Hi) Return -1; if (Time1-> Hi> Time2 -> hi) Return 1; if (Time1-> LO LO) RETURN -1; if (Time1-> Lo> Time2-> LO) Return 1; Return 0;} static void new_clock_seq (void) {Clock_Seq = (clock_seq 1)% (CLOCK_SEQ_LAST 1); if (clock_seq == 0) clock_seq = 1; #ifdef NONVOLATILE_CLOCK write_clock (clock_seq); #endif} void uuid_create (uuid_t * uuid) {static unsigned64_t time_now;

转载请注明原文地址:https://www.9cbs.com/read-63383.html

New Post(0)