PageRenderTime 119ms CodeModel.GetById 31ms app.highlight 81ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/lluuid.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 924 lines | 651 code | 104 blank | 169 comment | 126 complexity | 026675afc5272f70873b23a53744e453 MD5 | raw file
  1/** 
  2 * @file lluuid.cpp
  3 *
  4 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  5 * Second Life Viewer Source Code
  6 * Copyright (C) 2010, Linden Research, Inc.
  7 * 
  8 * This library is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU Lesser General Public
 10 * License as published by the Free Software Foundation;
 11 * version 2.1 of the License only.
 12 * 
 13 * This library is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * Lesser General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU Lesser General Public
 19 * License along with this library; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 21 * 
 22 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 23 * $/LicenseInfo$
 24 */
 25
 26#include "linden_common.h"
 27
 28// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.
 29#if LL_WINDOWS
 30#undef WIN32_LEAN_AND_MEAN
 31#include <winsock2.h>
 32#include <windows.h>
 33// ugh, this is ugly.  We need to straighten out our linking for this library
 34#pragma comment(lib, "IPHLPAPI.lib")
 35#include <iphlpapi.h>
 36#endif
 37
 38#include "lldefs.h"
 39#include "llerror.h"
 40
 41#include "lluuid.h"
 42#include "llerror.h"
 43#include "llrand.h"
 44#include "llmd5.h"
 45#include "llstring.h"
 46#include "lltimer.h"
 47
 48const LLUUID LLUUID::null;
 49const LLTransactionID LLTransactionID::tnull;
 50
 51/*
 52
 53NOT DONE YET!!!
 54
 55static char BASE85_TABLE[] = {
 56	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 57	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
 58	'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
 59	'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
 60	'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
 61	'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
 62	'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*',
 63	'+', '-', ';', '[', '=', '>', '?', '@', '^', '_',
 64	'`', '{', '|', '}', '~', '\0'
 65};
 66
 67
 68void encode( char * fiveChars, unsigned int word ) throw( )
 69{
 70for( int ix = 0; ix < 5; ++ix ) {
 71fiveChars[4-ix] = encodeTable[ word % 85];
 72word /= 85;
 73}
 74}
 75
 76To decode:
 77unsigned int decode( char const * fiveChars ) throw( bad_input_data )
 78{
 79unsigned int ret = 0;
 80for( int ix = 0; ix < 5; ++ix ) {
 81char * s = strchr( encodeTable, fiveChars[ ix ] );
 82if( s == 0 ) throw bad_input_data();
 83ret = ret * 85 + (s-encodeTable);
 84}
 85return ret;
 86}
 87
 88void LLUUID::toBase85(char* out)
 89{
 90	U32* me = (U32*)&(mData[0]);
 91	for(S32 i = 0; i < 4; ++i)
 92	{
 93		char* o = &out[i*i];
 94		for(S32 j = 0; j < 5; ++j)
 95		{
 96			o[4-j] = BASE85_TABLE[ me[i] % 85];
 97			word /= 85;
 98		}
 99	}
100}
101
102unsigned int decode( char const * fiveChars ) throw( bad_input_data )
103{
104	unsigned int ret = 0;
105	for( S32 ix = 0; ix < 5; ++ix )
106	{
107		char * s = strchr( encodeTable, fiveChars[ ix ] );
108		ret = ret * 85 + (s-encodeTable);
109	}
110	return ret;
111} 
112*/
113
114#define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0
115#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
116/**
117 * @brief a global for
118 */
119static U64 sJankyRandomSeed(LLUUID::getRandomSeed());
120
121/**
122 * @brief generate a random U32.
123 */
124U32 janky_fast_random_bytes()
125{
126	sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); 
127	return (U32)sJankyRandomSeed;
128}
129
130/**
131 * @brief generate a random U32 from [0, val)
132 */
133U32 janky_fast_random_byes_range(U32 val)
134{
135	sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); 
136	return (U32)(sJankyRandomSeed) % val; 
137}
138
139/**
140 * @brief generate a random U32 from [0, val)
141 */
142U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)
143{
144	seed = U64L(1664525) * (U64)(seed) + U64L(1013904223); 
145	return (U32)(seed) % val; 
146}
147#endif
148
149// Common to all UUID implementations
150void LLUUID::toString(std::string& out) const
151{
152	out = llformat(
153		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
154		(U8)(mData[0]),
155		(U8)(mData[1]),
156		(U8)(mData[2]),
157		(U8)(mData[3]),
158		(U8)(mData[4]),
159		(U8)(mData[5]),
160		(U8)(mData[6]),
161		(U8)(mData[7]),
162		(U8)(mData[8]),
163		(U8)(mData[9]),
164		(U8)(mData[10]),
165		(U8)(mData[11]),
166		(U8)(mData[12]),
167		(U8)(mData[13]),
168		(U8)(mData[14]),
169		(U8)(mData[15]));
170}
171
172// *TODO: deprecate
173void LLUUID::toString(char *out) const
174{
175	std::string buffer;
176	toString(buffer);
177	strcpy(out,buffer.c_str()); /* Flawfinder: ignore */
178}
179
180void LLUUID::toCompressedString(std::string& out) const
181{
182	char bytes[UUID_BYTES+1];
183	memcpy(bytes, mData, UUID_BYTES);		/* Flawfinder: ignore */
184	bytes[UUID_BYTES] = '\0';
185	out.assign(bytes, UUID_BYTES);
186}
187
188// *TODO: deprecate
189void LLUUID::toCompressedString(char *out) const
190{
191	memcpy(out, mData, UUID_BYTES);		/* Flawfinder: ignore */
192	out[UUID_BYTES] = '\0';
193}
194
195std::string LLUUID::getString() const
196{
197	return asString();
198}
199
200std::string LLUUID::asString() const
201{
202	std::string str;
203	toString(str);
204	return str;
205}
206
207BOOL LLUUID::set(const char* in_string, BOOL emit)
208{
209	return set(ll_safe_string(in_string),emit);
210}
211
212BOOL LLUUID::set(const std::string& in_string, BOOL emit)
213{
214	BOOL broken_format = FALSE;
215
216	// empty strings should make NULL uuid
217	if (in_string.empty())
218	{
219		setNull();
220		return TRUE;
221	}
222
223	if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */
224	{
225		// I'm a moron.  First implementation didn't have the right UUID format.
226		// Shouldn't see any of these any more
227		if (in_string.length() == (UUID_STR_LENGTH - 2))	/* Flawfinder: ignore */
228		{
229			if(emit)
230			{
231				llwarns << "Warning! Using broken UUID string format" << llendl;
232			}
233			broken_format = TRUE;
234		}
235		else
236		{
237			// Bad UUID string.  Spam as INFO, as most cases we don't care.
238			if(emit)
239			{
240				//don't spam the logs because a resident can't spell.
241				llwarns << "Bad UUID string: " << in_string << llendl;
242			}
243			setNull();
244			return FALSE;
245		}
246	}
247
248	U8 cur_pos = 0;
249	S32 i;
250	for (i = 0; i < UUID_BYTES; i++)
251	{
252		if ((i == 4) || (i == 6) || (i == 8) || (i == 10))
253		{
254			cur_pos++;
255			if (broken_format && (i==10))
256			{
257				// Missing - in the broken format
258				cur_pos--;
259			}
260		}
261
262		mData[i] = 0;
263
264		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9'))
265		{
266			mData[i] += (U8)(in_string[cur_pos] - '0');
267		}
268		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f'))
269		{
270			mData[i] += (U8)(10 + in_string[cur_pos] - 'a');
271		}
272		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F'))
273		{
274			mData[i] += (U8)(10 + in_string[cur_pos] - 'A');
275		}
276		else
277		{
278			if(emit)
279			{							
280				llwarns << "Invalid UUID string character" << llendl;
281			}
282			setNull();
283			return FALSE;
284		}
285
286		mData[i] = mData[i] << 4;
287		cur_pos++;
288
289		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9'))
290		{
291			mData[i] += (U8)(in_string[cur_pos] - '0');
292		}
293		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f'))
294		{
295			mData[i] += (U8)(10 + in_string[cur_pos] - 'a');
296		}
297		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F'))
298		{
299			mData[i] += (U8)(10 + in_string[cur_pos] - 'A');
300		}
301		else
302		{
303			if(emit)
304			{
305				llwarns << "Invalid UUID string character" << llendl;
306			}
307			setNull();
308			return FALSE;
309		}
310		cur_pos++;
311	}
312
313	return TRUE;
314}
315
316BOOL LLUUID::validate(const std::string& in_string)
317{
318	BOOL broken_format = FALSE;
319	if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */
320	{
321		// I'm a moron.  First implementation didn't have the right UUID format.
322		if (in_string.length() == (UUID_STR_LENGTH - 2))		/* Flawfinder: ignore */
323		{
324			broken_format = TRUE;
325		}
326		else
327		{
328			return FALSE;
329		}
330	}
331
332	U8 cur_pos = 0;
333	for (U32 i = 0; i < 16; i++)
334	{
335		if ((i == 4) || (i == 6) || (i == 8) || (i == 10))
336		{
337			cur_pos++;
338			if (broken_format && (i==10))
339			{
340				// Missing - in the broken format
341				cur_pos--;
342			}
343		}
344
345		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9'))
346		{
347		}
348		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f'))
349		{
350		}
351		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F'))
352		{
353		}
354		else
355		{
356			return FALSE;
357		}
358
359		cur_pos++;
360
361		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9'))
362		{
363		}
364		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f'))
365		{
366		}
367		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F'))
368		{
369		}
370		else
371		{
372			return FALSE;
373		}
374		cur_pos++;
375	}
376	return TRUE;
377}
378
379const LLUUID& LLUUID::operator^=(const LLUUID& rhs)
380{
381	U32* me = (U32*)&(mData[0]);
382	const U32* other = (U32*)&(rhs.mData[0]);
383	for(S32 i = 0; i < 4; ++i)
384	{
385		me[i] = me[i] ^ other[i];
386	}
387	return *this;
388}
389
390LLUUID LLUUID::operator^(const LLUUID& rhs) const
391{
392	LLUUID id(*this);
393	id ^= rhs;
394	return id;
395}
396
397void LLUUID::combine(const LLUUID& other, LLUUID& result) const
398{
399	LLMD5 md5_uuid;
400	md5_uuid.update((unsigned char*)mData, 16);
401	md5_uuid.update((unsigned char*)other.mData, 16);
402	md5_uuid.finalize();
403	md5_uuid.raw_digest(result.mData);
404}
405
406LLUUID LLUUID::combine(const LLUUID &other) const
407{
408	LLUUID combination;
409	combine(other, combination);
410	return combination;
411}
412
413std::ostream& operator<<(std::ostream& s, const LLUUID &uuid)
414{
415	std::string uuid_str;
416	uuid.toString(uuid_str);
417	s << uuid_str;
418	return s;
419}
420
421std::istream& operator>>(std::istream &s, LLUUID &uuid)
422{
423	U32 i;
424	char uuid_str[UUID_STR_LENGTH];		/* Flawfinder: ignore */
425	for (i = 0; i < UUID_STR_LENGTH-1; i++)
426	{
427		s >> uuid_str[i];
428	}
429	uuid_str[i] = '\0';
430	uuid.set(std::string(uuid_str));
431	return s;
432}
433
434static void get_random_bytes(void *buf, int nbytes)
435{
436	int i;
437	char *cp = (char *) buf;
438
439	// *NOTE: If we are not using the janky generator ll_rand()
440	// generates at least 3 good bytes of data since it is 0 to
441	// RAND_MAX. This could be made more efficient by copying all the
442	// bytes.
443	for (i=0; i < nbytes; i++)
444#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
445		*cp++ = janky_fast_random_bytes() & 0xFF;
446#else
447		*cp++ = ll_rand() & 0xFF;
448#endif
449	return;	
450}
451
452#if	LL_WINDOWS
453
454typedef struct _ASTAT_
455{
456	ADAPTER_STATUS adapt;
457	NAME_BUFFER    NameBuff [30];
458}ASTAT, * PASTAT;
459
460// static
461S32	LLUUID::getNodeID(unsigned char	*node_id)
462{
463	ASTAT Adapter;
464	NCB Ncb;
465	UCHAR uRetCode;
466	LANA_ENUM   lenum;
467	int      i;
468	int retval = 0;
469
470	memset( &Ncb, 0, sizeof(Ncb) );
471	Ncb.ncb_command = NCBENUM;
472	Ncb.ncb_buffer = (UCHAR *)&lenum;
473	Ncb.ncb_length = sizeof(lenum);
474	uRetCode = Netbios( &Ncb );
475
476	for(i=0; i < lenum.length ;i++)
477	{
478		memset( &Ncb, 0, sizeof(Ncb) );
479		Ncb.ncb_command = NCBRESET;
480		Ncb.ncb_lana_num = lenum.lana[i];
481
482		uRetCode = Netbios( &Ncb );
483
484		memset( &Ncb, 0, sizeof (Ncb) );
485		Ncb.ncb_command = NCBASTAT;
486		Ncb.ncb_lana_num = lenum.lana[i];
487
488		strcpy( (char *)Ncb.ncb_callname,  "*              " );		/* Flawfinder: ignore */
489		Ncb.ncb_buffer = (unsigned char *)&Adapter;
490		Ncb.ncb_length = sizeof(Adapter);
491
492		uRetCode = Netbios( &Ncb );
493		if ( uRetCode == 0 )
494		{
495			memcpy(node_id,Adapter.adapt.adapter_address,6);		/* Flawfinder: ignore */
496			retval = 1;
497		}
498	}
499	return retval;
500}
501
502#elif LL_DARWIN
503// Mac OS X version of the UUID generation code...
504/*
505 * Get an ethernet hardware address, if we can find it...
506 */
507#include <unistd.h>
508#include <sys/types.h>
509#include <sys/time.h>
510#include <sys/socket.h>
511#include <sys/ioctl.h>
512#include <net/if.h>
513#include <net/if_types.h>
514#include <net/if_dl.h>
515#include <net/route.h>
516#include <ifaddrs.h>
517
518// static
519S32 LLUUID::getNodeID(unsigned char *node_id)
520{
521	int i;
522	unsigned char 	*a = NULL;
523	struct ifaddrs *ifap, *ifa;
524	int rv;
525	S32 result = 0;
526
527	if ((rv=getifaddrs(&ifap))==-1)
528	{       
529		return -1;
530	}
531	if (ifap == NULL)
532	{
533		return -1;
534	}
535
536	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
537	{       
538//		printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family);
539		for(i=0; i< ifa->ifa_addr->sa_len; i++)
540		{
541//			printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]);
542		}
543//		printf("\n");
544		
545		if(ifa->ifa_addr->sa_family == AF_LINK)
546		{
547			// This is a link-level address
548			struct sockaddr_dl *lla = (struct sockaddr_dl *)ifa->ifa_addr;
549			
550//			printf("\tLink level address, type %02X\n", lla->sdl_type);
551
552			if(lla->sdl_type == IFT_ETHER)
553			{
554				// Use the first ethernet MAC in the list.
555				// For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly.  This is what it would do.
556				a = (unsigned char *)&((lla)->sdl_data);
557				a += (lla)->sdl_nlen;
558				
559				if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
560				{
561					continue;
562				}
563
564				if (node_id) 
565				{
566					memcpy(node_id, a, 6);
567					result = 1;
568				}
569				
570				// We found one.
571				break;
572			}
573		}
574	}
575	freeifaddrs(ifap);
576
577	return result;
578}
579
580#else
581
582// Linux version of the UUID generation code...
583/*
584 * Get the ethernet hardware address, if we can find it...
585 */
586#include <unistd.h>
587#include <fcntl.h>
588#include <errno.h>
589#include <sys/types.h>
590#include <sys/time.h>
591#include <sys/stat.h>
592#include <sys/file.h>
593#include <sys/ioctl.h>
594#include <sys/socket.h>
595#include <net/if.h>
596#define HAVE_NETINET_IN_H
597#ifdef HAVE_NETINET_IN_H
598#include <netinet/in.h>
599#if LL_SOLARIS
600#include <sys/sockio.h>
601#elif !LL_DARWIN
602#include <linux/sockios.h>
603#endif
604#endif
605
606// static
607S32 LLUUID::getNodeID(unsigned char *node_id)
608{
609	int 		sd;
610	struct ifreq 	ifr, *ifrp;
611	struct ifconf 	ifc;
612	char buf[1024];
613	int		n, i;
614	unsigned char 	*a;
615	
616/*
617 * BSD 4.4 defines the size of an ifreq to be
618 * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
619 * However, under earlier systems, sa_len isn't present, so the size is 
620 * just sizeof(struct ifreq)
621 */
622#ifdef HAVE_SA_LEN
623#ifndef max
624#define max(a,b) ((a) > (b) ? (a) : (b))
625#endif
626#define ifreq_size(i) max(sizeof(struct ifreq),\
627     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
628#else
629#define ifreq_size(i) sizeof(struct ifreq)
630#endif /* HAVE_SA_LEN*/
631
632	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
633	if (sd < 0) {
634		return -1;
635	}
636	memset(buf, 0, sizeof(buf));
637	ifc.ifc_len = sizeof(buf);
638	ifc.ifc_buf = buf;
639	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
640		close(sd);
641		return -1;
642	}
643	n = ifc.ifc_len;
644	for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
645		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
646		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);		/* Flawfinder: ignore */
647#ifdef SIOCGIFHWADDR
648		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
649			continue;
650		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
651#else
652#ifdef SIOCGENADDR
653		if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
654			continue;
655		a = (unsigned char *) ifr.ifr_enaddr;
656#else
657		/*
658		 * XXX we don't have a way of getting the hardware
659		 * address
660		 */
661		close(sd);
662		return 0;
663#endif /* SIOCGENADDR */
664#endif /* SIOCGIFHWADDR */
665		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
666			continue;
667		if (node_id) {
668			memcpy(node_id, a, 6);		/* Flawfinder: ignore */
669			close(sd);
670			return 1;
671		}
672	}
673	close(sd);
674	return 0;
675}
676
677#endif
678
679S32 LLUUID::cmpTime(uuid_time_t *t1, uuid_time_t *t2)
680{
681   // Compare two time values.
682
683   if (t1->high < t2->high) return -1;
684   if (t1->high > t2->high) return 1;
685   if (t1->low  < t2->low)  return -1;
686   if (t1->low  > t2->low)  return 1;
687   return 0;
688}
689
690void LLUUID::getSystemTime(uuid_time_t *timestamp)
691{
692   // Get system time with 100ns precision. Time is since Oct 15, 1582.
693#if LL_WINDOWS
694   ULARGE_INTEGER time;
695   GetSystemTimeAsFileTime((FILETIME *)&time);
696   // NT keeps time in FILETIME format which is 100ns ticks since
697   // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582.
698   // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec)
699   // + 18 years and 5 leap days.
700   time.QuadPart +=
701            (unsigned __int64) (1000*1000*10)       // seconds
702          * (unsigned __int64) (60 * 60 * 24)       // days
703          * (unsigned __int64) (17+30+31+365*18+5); // # of days
704
705   timestamp->high = time.HighPart;
706   timestamp->low  = time.LowPart;
707#else
708   struct timeval tp;
709   gettimeofday(&tp, 0);
710
711   // Offset between UUID formatted times and Unix formatted times.
712   // UUID UTC base time is October 15, 1582.
713   // Unix base time is January 1, 1970.
714   U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) +
715                           U64L(0x01B21DD213814000);
716   timestamp->high = (U32) (uuid_time >> 32);
717   timestamp->low  = (U32) (uuid_time & 0xFFFFFFFF);
718#endif
719}
720
721void LLUUID::getCurrentTime(uuid_time_t *timestamp)
722{
723   // Get current time as 60 bit 100ns ticks since whenever.
724   // Compensate for the fact that real clock resolution is less
725   // than 100ns.
726
727   const U32 uuids_per_tick = 1024;
728
729   static uuid_time_t time_last;
730   static U32    uuids_this_tick;
731   static BOOL     init = FALSE;
732
733   if (!init) {
734      getSystemTime(&time_last);
735      uuids_this_tick = uuids_per_tick;
736      init = TRUE;
737   }
738
739   uuid_time_t time_now = {0,0};
740
741   while (1) {
742      getSystemTime(&time_now);
743
744      // if clock reading changed since last UUID generated
745      if (cmpTime(&time_last, &time_now))  {
746         // reset count of uuid's generated with this clock reading
747         uuids_this_tick = 0;
748         break;
749      }
750      if (uuids_this_tick < uuids_per_tick) {
751         uuids_this_tick++;
752         break;
753      }
754      // going too fast for our clock; spin
755   }
756
757   time_last = time_now;
758
759   if (uuids_this_tick != 0) {
760      if (time_now.low & 0x80000000) {
761         time_now.low += uuids_this_tick;
762         if (!(time_now.low & 0x80000000))
763            time_now.high++;
764      } else
765         time_now.low += uuids_this_tick;
766   }
767
768   timestamp->high = time_now.high;
769   timestamp->low  = time_now.low;
770}
771
772void LLUUID::generate()
773{
774	// Create a UUID.
775	uuid_time_t timestamp;
776
777	static unsigned char node_id[6];	/* Flawfinder: ignore */
778	static int has_init = 0;
779   
780	// Create a UUID.
781	static uuid_time_t time_last = {0,0};
782	static U16 clock_seq = 0;
783#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
784	static U32 seed = 0L; // dummy seed.  reset it below
785#endif
786	if (!has_init) 
787	{
788		if (getNodeID(node_id) <= 0) 
789		{
790			get_random_bytes(node_id, 6);
791			/*
792			 * Set multicast bit, to prevent conflicts
793			 * with IEEE 802 addresses obtained from
794			 * network cards
795			 */
796			node_id[0] |= 0x80;
797		}
798
799		getCurrentTime(&time_last);
800#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
801		seed = time_last.low;
802#endif
803
804#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
805		clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536);
806#else
807		clock_seq = (U16)ll_rand(65536);
808#endif
809		has_init = 1;
810	}
811
812	// get current time
813	getCurrentTime(&timestamp);
814
815	// if clock went backward change clockseq
816	if (cmpTime(&timestamp, &time_last) == -1) {
817		clock_seq = (clock_seq + 1) & 0x3FFF;
818		if (clock_seq == 0) clock_seq++;
819	}
820
821	memcpy(mData+10, node_id, 6);		/* Flawfinder: ignore */
822	U32 tmp;
823	tmp = timestamp.low;
824	mData[3] = (unsigned char) tmp;
825	tmp >>= 8;
826	mData[2] = (unsigned char) tmp;
827	tmp >>= 8;
828	mData[1] = (unsigned char) tmp;
829	tmp >>= 8;
830	mData[0] = (unsigned char) tmp;
831	
832	tmp = (U16) timestamp.high;
833	mData[5] = (unsigned char) tmp;
834	tmp >>= 8;
835	mData[4] = (unsigned char) tmp;
836
837	tmp = (timestamp.high >> 16) | 0x1000;
838	mData[7] = (unsigned char) tmp;
839	tmp >>= 8;
840	mData[6] = (unsigned char) tmp;
841
842	tmp = clock_seq;
843	mData[9] = (unsigned char) tmp;
844	tmp >>= 8;
845	mData[8] = (unsigned char) tmp;
846
847	LLMD5 md5_uuid;
848	
849	md5_uuid.update(mData,16);
850	md5_uuid.finalize();
851	md5_uuid.raw_digest(mData);
852
853    time_last = timestamp;
854}
855
856void LLUUID::generate(const std::string& hash_string)
857{
858	LLMD5 md5_uuid((U8*)hash_string.c_str());
859	md5_uuid.raw_digest(mData);
860}
861
862U32 LLUUID::getRandomSeed()
863{
864   static unsigned char seed[16];		/* Flawfinder: ignore */
865   
866   getNodeID(&seed[0]);
867   seed[6]='\0';
868   seed[7]='\0';
869   getSystemTime((uuid_time_t *)(&seed[8]));
870
871   LLMD5 md5_seed;
872	
873   md5_seed.update(seed,16);
874   md5_seed.finalize();
875   md5_seed.raw_digest(seed);
876   
877   return(*(U32 *)seed);
878}
879
880BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value)
881{
882	if( buf.empty() || value == NULL)
883	{
884		return FALSE;
885	}
886
887	std::string temp( buf );
888	LLStringUtil::trim(temp);
889	if( LLUUID::validate( temp ) )
890	{
891		value->set( temp );
892		return TRUE;
893	}
894	return FALSE;
895}
896
897//static
898LLUUID LLUUID::generateNewID(std::string hash_string)
899{
900	LLUUID new_id;
901	if (hash_string.empty())
902	{
903		new_id.generate();
904	}
905	else
906	{
907		new_id.generate(hash_string);
908	}
909	return new_id;
910}
911
912LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
913{
914	LLAssetID result;
915	if (isNull())
916	{
917		result.setNull();
918	}
919	else
920	{
921		combine(session, result);
922	}
923	return result;
924}