lluuid.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:21k
源码类别:

游戏引擎

开发平台:

C++ Builder

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