forked from cloudfreexiao/lcrypt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuuid.c
executable file
·58 lines (46 loc) · 1.76 KB
/
uuid.c
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
#include "lcrypt.h"
#define UUID_V4_LENGTH 36
#define GUID_V1_LENGTH 35
static inline const char* uuid_v4_gen(char *buffer) {
union {
struct {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clk_seq_hi_res;
uint8_t clk_seq_low;
uint8_t node[6];
};
uint8_t __rnd[16];
} uuid;
RAND_bytes(uuid.__rnd, sizeof(uuid));
uuid.clk_seq_hi_res = (uint8_t) ((uuid.clk_seq_hi_res & 0x3F) | 0x80);
uuid.time_hi_and_version = (uint16_t) ((uuid.time_hi_and_version & 0x0FFF) | 0x4000);
snprintf(buffer, UUID_V4_LENGTH + 1, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
uuid.clk_seq_hi_res, uuid.clk_seq_low,
uuid.node[0], uuid.node[1], uuid.node[2],
uuid.node[3], uuid.node[4], uuid.node[5]
);
buffer[UUID_V4_LENGTH] = '\0';
return (const char*) buffer;
}
static inline const char* guid_v1_gen(const uint8_t *hash, char *buffer, uint32_t hi, uint32_t low) {
uint8_t rand_bytes[2]; RAND_bytes(rand_bytes, 2);
snprintf(buffer, GUID_V1_LENGTH + 1, "%02x%02x%02x%02x%02x%02x%02x%02x-%08x-%04x-%02x%02x",
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7],
hi, low, rand_bytes[0], rand_bytes[1]
);
buffer[GUID_V1_LENGTH] = '\0';
return (const char*) buffer;
}
int luuid(lua_State *L) {
lua_pushlstring(L, (const char *)uuid_v4_gen(lua_newuserdata(L, UUID_V4_LENGTH + 1)), UUID_V4_LENGTH);
return 1;
}
int lguid(lua_State *L) {
if (1 != lhashkey(L))
return luaL_error(L, "Invalid hashkey.");
lua_pushlstring(L, (const char *)guid_v1_gen((const uint8_t *)lua_tostring(L, 4), lua_newuserdata(L, GUID_V1_LENGTH + 1), lua_tointeger(L, 2), lua_tointeger(L, 3)), GUID_V1_LENGTH);
return 1;
}