unique_id.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* Copyright (c) 1994 FUJITSU LIMITED */
  24. /* All Rights Reserved */
  25. /*
  26. * $XConsortium: unique_id.c /main/3 1996/06/11 17:40:45 cde-hal $
  27. *
  28. * Copyright (c) 1992 HAL Computer Systems International, Ltd.
  29. * All rights reserved. Unpublished -- rights reserved under
  30. * the Copyright Laws of the United States. USE OF A COPYRIGHT
  31. * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
  32. * OR DISCLOSURE.
  33. *
  34. * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
  35. * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. USE,
  36. * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
  37. * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
  38. * INTERNATIONAL, LTD.
  39. *
  40. * RESTRICTED RIGHTS LEGEND
  41. * Use, duplication, or disclosure by the Government is subject
  42. * to the restrictions as set forth in subparagraph (c)(l)(ii)
  43. * of the Rights in Technical Data and Computer Software clause
  44. * at DFARS 252.227-7013.
  45. *
  46. * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
  47. * 1315 Dell Avenue
  48. * Campbell, CA 95008
  49. *
  50. */
  51. #include <sys/types.h>
  52. #include <sys/time.h>
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <unistd.h>
  56. #include <ctype.h>
  57. #ifdef SVR4
  58. #include <sys/systeminfo.h>
  59. #endif
  60. /* **************************************************************
  61. * unique_id - generate a 15 character NULL terminated id
  62. * ************************************************************** */
  63. /* This code assumes:
  64. sizeof (time_t) == 4,
  65. sizeof (int) == 4,
  66. sizeof (short) == 2,
  67. sizeof ("hostid") == 4,
  68. sizeof ("pid") == 2,
  69. */
  70. /* #define DEBUG */
  71. static char mapping[] =
  72. { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  73. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
  74. 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  75. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
  76. 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
  77. '.', '_' };
  78. static unsigned int mask[] =
  79. { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
  80. #define COPY_BITS(DEST,DPOS,SRC,SPOS,LEN) \
  81. DEST |= ((SRC & (mask[LEN] << SPOS)) >> SPOS) << DPOS;
  82. #define PRINT_BITS(BITS) \
  83. { int i; unsigned long bits = BITS; printf (#BITS " = 0x%04x", BITS); \
  84. for (i = 0; i < sizeof(BITS) * 8; i++, bits <<= 1) { \
  85. if (!(i%4)) putchar (' '); \
  86. (bits & (1L << (sizeof(BITS) * 8)-1)) ? putchar('1') : putchar('0'); } \
  87. putchar ('\n'); }
  88. #if defined(SVR4) && !defined(sun)
  89. static unsigned int
  90. gethostid()
  91. {
  92. char buffer[256];
  93. sysinfo (SI_HW_SERIAL, buffer, sizeof (buffer));
  94. return (atoi (buffer));
  95. }
  96. #endif
  97. const char *
  98. unique_id (void)
  99. {
  100. static char buf[16];
  101. static unsigned int hostid;
  102. static struct timeval cur_time, old_time;
  103. static unsigned short pid;
  104. static int i;
  105. /* -------- First get the information -------- */
  106. /* Loop until first char is alpha-numeric. */
  107. do
  108. {
  109. /* Loop over time until unique. */
  110. do
  111. {
  112. /* Failure of this call is catastrophic: */
  113. if (gettimeofday (&cur_time, NULL) == -1)
  114. {
  115. perror ("unique_id:gettimeofday");
  116. abort();
  117. }
  118. /* Truncate microseconds to milliseconds. */
  119. cur_time.tv_usec /= 1000;
  120. }
  121. while (cur_time.tv_usec == old_time.tv_usec &&
  122. cur_time.tv_sec == old_time.tv_sec);
  123. old_time.tv_usec = cur_time.tv_usec;
  124. old_time.tv_sec = cur_time.tv_sec;
  125. if (pid == 0)
  126. pid = getpid();
  127. if (hostid == 0)
  128. hostid = gethostid();
  129. #ifdef DEBUG
  130. PRINT_BITS ((unsigned int)cur_time.tv_usec);
  131. PRINT_BITS ((unsigned int)cur_time.tv_sec);
  132. PRINT_BITS (pid);
  133. PRINT_BITS (hostid);
  134. #endif
  135. for (i = 0; i < 15; i++)
  136. buf[i] = 0;
  137. COPY_BITS (buf[0], 0, cur_time.tv_usec, 0, 6);
  138. COPY_BITS (buf[1], 0, cur_time.tv_usec, 6, 4);
  139. COPY_BITS (buf[1], 4, cur_time.tv_sec, 0, 2);
  140. COPY_BITS (buf[2], 0, cur_time.tv_sec, 2, 6);
  141. COPY_BITS (buf[3], 0, cur_time.tv_sec, 8, 6);
  142. COPY_BITS (buf[4], 0, cur_time.tv_sec, 14, 6);
  143. COPY_BITS (buf[5], 0, cur_time.tv_sec, 20, 6);
  144. COPY_BITS (buf[6], 0, cur_time.tv_sec, 26, 6);
  145. COPY_BITS (buf[7], 0, pid, 0, 6);
  146. COPY_BITS (buf[8], 0, pid, 6, 6);
  147. COPY_BITS (buf[9], 0, pid, 12, 4);
  148. COPY_BITS (buf[9], 4, hostid, 0, 2);
  149. COPY_BITS (buf[10], 0, hostid, 2, 6);
  150. COPY_BITS (buf[11], 0, hostid, 8, 6);
  151. COPY_BITS (buf[12], 0, hostid, 14, 6);
  152. COPY_BITS (buf[13], 0, hostid, 20, 6);
  153. COPY_BITS (buf[14], 0, hostid, 26, 6);
  154. for (i = 0; i < 15; i++)
  155. {
  156. #ifdef DEBUG
  157. unsigned char ch = buf[i];
  158. printf ("%2d 0x%02x ", i, ch);
  159. PRINT_BITS (ch);
  160. #endif
  161. buf[i] = mapping[(int)buf[i]];
  162. }
  163. } while (!isalnum ((unsigned char) buf[0]));
  164. return (buf);
  165. }
  166. #ifdef TEST
  167. int
  168. main (int argc, char **argv)
  169. {
  170. int count = 0;
  171. int i;
  172. if (argc == 1)
  173. count = 1;
  174. else if (argc == 2)
  175. count = atoi (argv[1]);
  176. if (count == 0)
  177. {
  178. printf (stderr, "usage: uid [count]");
  179. exit (1);
  180. }
  181. printf ("Generating %d unique ids\n", count);
  182. for (i = 0; i < count; i++)
  183. puts (unique_id());
  184. }
  185. #endif /* TEST */