File: gen.c

package info (click to toggle)
libuuid-perl 0.37-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,092 kB
  • sloc: ansic: 2,374; perl: 580; makefile: 5
file content (168 lines) | stat: -rw-r--r-- 4,920 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#ifdef __cplusplus
extern "C" {
#endif

#include "ulib/chacha.h"
#include "ulib/clock.h"
#include "ulib/gen.h"
#include "ulib/md5.h"
#include "ulib/node.h"
#include "ulib/sha1.h"

#ifdef __cplusplus
}
#endif


/* randomize uu_node */
static void uu_gen_randomize(pUCXT) {
  cc_rand32(aUCXT, (U32*)&UCXT.gen_node[0]);
  cc_rand16(aUCXT, (U16*)&UCXT.gen_node[4]);
  UCXT.gen_node[0] |= 0x01; /* set mcast */
}

/* call at boot */
void uu_gen_init(pUCXT) {
  UCXT.gen_epoch = (((U64) 0x01B21DD2) << 32) | 0x13814000; /* unused */
  UCXT.gen_use_unique = 0;
  UCXT.gen_has_real_node = 0;
  UCXT.gen_node[0] = 0;;
  UCXT.gen_node[1] = 0;;
  UCXT.gen_node[2] = 0;;
  UCXT.gen_node[3] = 0;;
  UCXT.gen_node[4] = 0;;
  UCXT.gen_node[5] = 0;;
  UCXT.gen_real_node[0] = 0;
  UCXT.gen_real_node[1] = 0;
  UCXT.gen_real_node[2] = 0;
  UCXT.gen_real_node[3] = 0;
  UCXT.gen_real_node[4] = 0;
  UCXT.gen_real_node[5] = 0;

  /* get the real node or randomize it */
  if (uu_get_node_id(aUCXT, (U8*)&UCXT.gen_node) == 1) {
    UCXT.gen_has_real_node = 1;
    UCXT.gen_real_node[0] = UCXT.gen_node[0];
    UCXT.gen_real_node[1] = UCXT.gen_node[1];
    UCXT.gen_real_node[2] = UCXT.gen_node[2];
    UCXT.gen_real_node[3] = UCXT.gen_node[3];
    UCXT.gen_real_node[4] = UCXT.gen_node[4];
    UCXT.gen_real_node[5] = UCXT.gen_node[5];
  }
  else {
    UCXT.gen_has_real_node = 0;
    uu_gen_randomize(aUCXT);
  }
}

void uu_gen_setrand(pUCXT) {
  UCXT.gen_use_unique = 0;
  uu_gen_randomize(aUCXT);
}

void uu_gen_setuniq(pUCXT) {
  UCXT.gen_use_unique = 1;
}

/* returns 1 if has real node, or 0 */
int uu_realnode(pUCXT, struct_uu_t *out) {
  uu_v0gen(aUCXT, out, NULL);
  out->v1.node[0] = UCXT.gen_real_node[0];
  out->v1.node[1] = UCXT.gen_real_node[1];
  out->v1.node[2] = UCXT.gen_real_node[2];
  out->v1.node[3] = UCXT.gen_real_node[3];
  out->v1.node[4] = UCXT.gen_real_node[4];
  out->v1.node[5] = UCXT.gen_real_node[5];
  return UCXT.gen_has_real_node;
}


void uu_v0gen(pUCXT, struct_uu_t *out, char *dptr) {
  out->v0.low  = 0;
  out->v0.high = 0;
}

void uu_v1gen(pUCXT, struct_uu_t *out, char *dptr) {
  U64   clock_reg;
  U16   clock_seq;

  uu_clock(aUCXT, &clock_reg, &clock_seq);
  clock_reg += (((U64)0x01b21dd2) << 32) + 0x13814000;

  out->v1.time_low              = (U32)clock_reg;
  out->v1.time_mid              = (U16)(clock_reg >> 32 & 0xffff);
  out->v1.time_high_and_version = (U16)(clock_reg >> 48 & 0x0fff | 0x1000);
  out->v1.clock_seq_and_variant = clock_seq & 0x3fff | 0x8000;

  if (UCXT.gen_use_unique) uu_gen_randomize(aUCXT);
  out->v1.node[0] = UCXT.gen_node[0];
  out->v1.node[1] = UCXT.gen_node[1];
  out->v1.node[2] = UCXT.gen_node[2];
  out->v1.node[3] = UCXT.gen_node[3];
  out->v1.node[4] = UCXT.gen_node[4];
  out->v1.node[5] = UCXT.gen_node[5];
}

void uu_v3gen(pUCXT, struct_uu_t *out, char *dptr) {
  /* out points to a v1 uuid to use as namespace. */
  /* out also points to output buffer for v3 uuid. */
  /* dptr points to string to use as name. */
  uu_md5_hash(aUCXT, out, dptr);
}

void uu_v4gen(pUCXT, struct_uu_t *out, char *dptr) {
  U64 *cp = (U64*)out;

  cc_rand64(aUCXT, cp++);
  cc_rand64(aUCXT, cp);
  out->v4.rand_b_and_version = out->v4.rand_b_and_version & 0xffff0fff | 0x00004000;
  out->v4.rand_c_and_variant = out->v4.rand_c_and_variant & 0x3fffffff | 0x80000000;
}

void uu_v5gen(pUCXT, struct_uu_t *out, char *dptr) {
  /* out points to a v1 uuid to use as namespace. */
  /* out also points to output buffer for v5 uuid. */
  /* dptr points to string to use as name. */
  uu_sha_hash(aUCXT, out, dptr);
}

void uu_v6gen(pUCXT, struct_uu_t *out, char *dptr) {
  U64   clock_reg;
  U16   clock_seq;

  uu_clock(aUCXT, &clock_reg, &clock_seq);
  clock_reg += (((U64)0x01b21dd2) << 32) + 0x13814000;

  out->v6.time_high             = (U32)(clock_reg >> 28);
  out->v6.time_mid              = (U16)(clock_reg >> 12);
  out->v6.time_low_and_version  = (U16)clock_reg & 0x0fff | 0x6000;
  out->v6.clock_seq_and_variant = clock_seq & 0x3fff | 0x8000;

  /* use the same node as v1 */
  if (UCXT.gen_use_unique) uu_gen_randomize(aUCXT);
  out->v6.node[0] = UCXT.gen_node[0];
  out->v6.node[1] = UCXT.gen_node[1];
  out->v6.node[2] = UCXT.gen_node[2];
  out->v6.node[3] = UCXT.gen_node[3];
  out->v6.node[4] = UCXT.gen_node[4];
  out->v6.node[5] = UCXT.gen_node[5];
}

void uu_v7gen(pUCXT, struct_uu_t *out, char *dptr) {
  U64   clock_reg;
  U16   clock_seq;

  uu_clock(aUCXT, &clock_reg, &clock_seq);
  clock_reg /= 10000;

  cc_rand16(aUCXT, &out->v7.rand_a_and_version);
  cc_rand64(aUCXT, &out->v7.rand_b_and_variant);
  out->v7.time_high             = (U32)(clock_reg >> 16);
  out->v7.time_low              = (U16)(clock_reg & 0xffff);
  out->v7.rand_a_and_version = out->v7.rand_a_and_version & 0x0fff | 0x7000;
  out->v7.rand_b_and_variant = out->v7.rand_b_and_variant
    & 0x3fffffffffffffffULL
    | 0x8000000000000000ULL;
}

/* ex:set ts=2 sw=2 itab=spaces: */