1 #include "iwuuid.h"
2 #include "iwutils.h"
3 #include <string.h>
4
5 union _uuid {
6 uint8_t byte[16];
7 uint32_t rnd[4];
8 };
9
10 // [a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}
11
_is_uuid_char(char ch)12 IW_INLINE bool _is_uuid_char(char ch) {
13 return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9');
14 }
15
iwu_uuid_valid(const char * uuid)16 bool iwu_uuid_valid(const char *uuid) {
17 if (!uuid || strlen(uuid) != IW_UUID_STR_LEN) {
18 return false;
19 }
20 for (int i = 0; i < 8; ++i) {
21 if (!_is_uuid_char(uuid[i])) {
22 return false;
23 }
24 }
25 if (uuid[8] != '-') {
26 return false;
27 }
28 uuid += 9;
29 for (int j = 0; j < 3; ++j) {
30 for (int i = 0; i < 4; ++i) {
31 if (!_is_uuid_char(uuid[i])) {
32 return false;
33 }
34 }
35 if (uuid[4] != '-') {
36 return false;
37 }
38 uuid += 5;
39 }
40 for (int i = 0; i < 12; ++i) {
41 if (!_is_uuid_char(uuid[i])) {
42 return false;
43 }
44 }
45 return true;
46 }
47
iwu_uuid4_fill(char dest[static IW_UUID_STR_LEN])48 void iwu_uuid4_fill(char dest[static IW_UUID_STR_LEN]) {
49 char buf[IW_UUID_STR_LEN + 1];
50 union _uuid uuid;
51 for (size_t i = 0; i < 4; i++) {
52 uuid.rnd[i] = iwu_rand_u32();
53 }
54 uuid.byte[6] = (uuid.byte[6] & 0x0F) | 0x40;
55 uuid.byte[8] = (uuid.byte[8] & 0x3F) | 0x80;
56 snprintf(buf, IW_UUID_STR_LEN + 1, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
57 uuid.byte[0],
58 uuid.byte[1],
59 uuid.byte[2],
60 uuid.byte[3],
61 uuid.byte[4],
62 uuid.byte[5],
63 uuid.byte[6],
64 uuid.byte[7],
65 uuid.byte[8],
66 uuid.byte[9],
67 uuid.byte[10],
68 uuid.byte[11],
69 uuid.byte[12],
70 uuid.byte[13],
71 uuid.byte[14],
72 uuid.byte[15]);
73 memcpy(dest, buf, IW_UUID_STR_LEN);
74 }
75