ulid_fast 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 675e2d1ea39c7608d9bb84a96efeab8acdf7eef82c1dd294c300577db946f72e
4
+ data.tar.gz: a58b60f8ff7177465adb801d194d80e456cbcaa4f7b90ea9efdb7cda2d0666bb
5
+ SHA512:
6
+ metadata.gz: 2aa59ba886b3f1d00ade9e4f3aa5595d41ebf15ccc2ad0a841d4d88dc1e58b5c8954032a3a3403e3dba9f691e8bbdf2b79a130d3b454aec5f1ec34ec9154027e
7
+ data.tar.gz: 6805293e8c88cf1464cdebb3f157c5fc97749b85e53068bf29f4b22b3a370fc4f1bd1ebc92a08e7454f3e771b62acda7bed04b36d0d62ee6c37e96fffd46202c
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('ulid_fast')
@@ -0,0 +1,88 @@
1
+ #include <stdlib.h>
2
+ #include <ruby.h>
3
+ #include <ruby/encoding.h>
4
+ #include "ulid.h"
5
+
6
+
7
+ static VALUE m_ULID;
8
+
9
+
10
+ void
11
+ rb_ulid_generator_mark (void *_self)
12
+ {
13
+ /*
14
+ * This function is not needed becaue there is no malloc() or
15
+ * pointers to other VALUE objects.
16
+ * However, to help others understand how Ruby C extensions
17
+ * work I've left it here.
18
+ *
19
+ struct ulid_generator *ug;
20
+
21
+ TypedData_Get_Struct(self, struct ulid_generator, &UlidGeneratorType, ug);
22
+
23
+ rb_gc_mark(ug->thing);
24
+ rb_gc_mark(ug->other_thing);
25
+ */
26
+ }
27
+
28
+ void
29
+ rb_ulid_generator_free (void *_self)
30
+ {
31
+ // Not needed. We do not malloc() here or in the ulid lib
32
+ // free(_self);
33
+ }
34
+
35
+ static const rb_data_type_t UlidGeneratorType = {
36
+ "UlidGenerator",
37
+ { rb_ulid_generator_mark, rb_ulid_generator_free, NULL }
38
+ };
39
+
40
+ static VALUE
41
+ rb_ulid_generate(VALUE self)
42
+ {
43
+ struct ulid_generator *ug;
44
+
45
+ TypedData_Get_Struct(self, struct ulid_generator, &UlidGeneratorType, ug);
46
+ char ulid[27];
47
+
48
+ ulid_generate(ug, ulid);
49
+
50
+ return rb_utf8_str_new(ulid, 26);
51
+ }
52
+
53
+ static VALUE
54
+ rb_ulid_alloc(VALUE self)
55
+ {
56
+ struct ulid_generator *ug;
57
+ VALUE obj;
58
+ obj = TypedData_Make_Struct(self, struct ulid_generator, &UlidGeneratorType, ug);
59
+
60
+ int ret = ulid_generator_init(ug, ULID_SECURE);
61
+
62
+ if (ret != 0)
63
+ rb_raise(rb_eRuntimeError, "ulid_generator_init failure");
64
+
65
+ return obj;
66
+ }
67
+
68
+ // TODO ..
69
+ /*
70
+ static VALUE
71
+ rb_ulid_each(int argc, VALUE* argv, VALUE self)
72
+ {
73
+ // return rb_funcall(self, rb_intern("to_enum"), 2, rb_intern("generate"), self,);
74
+
75
+ return Qnil;
76
+ }
77
+ */
78
+
79
+ void
80
+ Init_ulid_fast() {
81
+ m_ULID = rb_define_module("ULID");
82
+
83
+ VALUE cls = rb_define_class_under(m_ULID, "Generator", rb_cObject);
84
+ // rb_include_module(m_ULID, rb_mEnumerable);
85
+ rb_define_alloc_func(cls, rb_ulid_alloc);
86
+ rb_define_method(cls, "generate", rb_ulid_generate, 0);
87
+ //rb_define_method(cls, "each", rb_ulid_each, -1);
88
+ }
@@ -0,0 +1,294 @@
1
+ /* ULID generation and parsing library (implementation)
2
+ *
3
+ * This is free and unencumbered software released into the public domain.
4
+ */
5
+ #ifdef _WIN32
6
+ # define WIN32_LEAN_AND_MEAN
7
+ # include <windows.h>
8
+ # pragma comment(lib, "advapi32.lib")
9
+ #elif __linux__
10
+ # define _GNU_SOURCE
11
+ # include <unistd.h>
12
+ # include <sys/time.h>
13
+ # include <sys/syscall.h>
14
+ #else
15
+ # define _POSIX_C_SOURCE 200112L
16
+ # include <sys/time.h>
17
+ #endif
18
+ #include <time.h>
19
+ #include <stdio.h>
20
+ #include <string.h>
21
+ #include "ulid.h"
22
+
23
+ /* Returns unix epoch microseconds.
24
+ */
25
+ static unsigned long long
26
+ platform_utime(int coarse)
27
+ {
28
+ #ifdef _WIN32
29
+ FILETIME ft;
30
+ (void)coarse;
31
+ GetSystemTimeAsFileTime(&ft);
32
+ return ((unsigned long long)ft.dwHighDateTime << 32 |
33
+ (unsigned long long)ft.dwLowDateTime << 0)
34
+ / 10 - 11644473600000000ULL;
35
+ #elif __linux__
36
+ /* CLOCK_REALTIME_COARSE has a resolution of 1ms, which is
37
+ * sufficient for this purpose. It's also _much_ faster.
38
+ */
39
+ struct timespec tv[1];
40
+ clock_gettime(coarse ? CLOCK_REALTIME_COARSE : CLOCK_REALTIME, tv);
41
+ return tv->tv_sec * 1000000ULL + tv->tv_nsec / 1000ULL;
42
+ #else
43
+ struct timespec tv[1];
44
+ (void)coarse;
45
+ clock_gettime(CLOCK_REALTIME, tv);
46
+ return tv->tv_sec * 1000000ULL + tv->tv_nsec / 1000ULL;
47
+ #endif
48
+ }
49
+
50
+ /* Gather entropy from the operating system.
51
+ * Returns 0 on success.
52
+ */
53
+ static int
54
+ platform_entropy(void *buf, int len)
55
+ {
56
+ #if _WIN32
57
+ BOOLEAN NTAPI SystemFunction036(PVOID, ULONG);
58
+ return !SystemFunction036(buf, len);
59
+ #elif __linux__
60
+ return syscall(SYS_getrandom, buf, len, 0) != len;
61
+ #else
62
+ int r = 0;
63
+ FILE *f = fopen("/dev/urandom", "rb");
64
+ if (f) {
65
+ r = fread(buf, len, 1, f);
66
+ fclose(f);
67
+ }
68
+ return !r;
69
+ #endif
70
+ }
71
+
72
+ int
73
+ ulid_generator_init(struct ulid_generator *g, int flags)
74
+ {
75
+ g->last_ts = 0;
76
+ g->flags = flags;
77
+ g->i = g->j = 0;
78
+ for (int i = 0; i < 256; i++)
79
+ g->s[i] = i;
80
+
81
+ /* RC4 is used to fill the random segment of ULIDs. It's tiny,
82
+ * simple, perfectly sufficient for the task (assuming it's seeded
83
+ * properly), and doesn't require fixed-width integers. It's not the
84
+ * fastest option, but it's plenty fast for the task.
85
+ *
86
+ * Besides, when we're in a serious hurry in normal operation (not
87
+ * in "relaxed" mode), we're incrementing the random field much more
88
+ * often than generating fresh random bytes.
89
+ */
90
+
91
+ int initstyle = 1;
92
+ unsigned char key[256] = {0};
93
+ if (!platform_entropy(key, 256)) {
94
+ /* Mix entropy into the RC4 state. */
95
+ for (int i = 0, j = 0; i < 256; i++) {
96
+ j = (j + g->s[i] + key[i]) & 0xff;
97
+ int tmp = g->s[i];
98
+ g->s[i] = g->s[j];
99
+ g->s[j] = tmp;
100
+ }
101
+ initstyle = 0;
102
+ } else if (!(flags & ULID_SECURE)) {
103
+ /* Failed to read entropy from OS, so generate some. */
104
+ unsigned long n = 0;
105
+ unsigned long long now;
106
+ unsigned long long start = platform_utime(0);
107
+ do {
108
+ struct {
109
+ clock_t clk;
110
+ unsigned long long ts;
111
+ long n;
112
+ void *stackgap;
113
+ } noise;
114
+ noise.ts = now = platform_utime(0);
115
+ noise.clk = clock();
116
+ noise.stackgap = &noise;
117
+ noise.n = n;
118
+ unsigned char *k = (unsigned char *)&noise;
119
+ for (int i = 0, j = 0; i < 256; i++) {
120
+ j = (j + g->s[i] + k[i % sizeof(noise)]) & 0xff;
121
+ int tmp = g->s[i];
122
+ g->s[i] = g->s[j];
123
+ g->s[j] = tmp;
124
+ }
125
+ } while (n++ < 1UL << 16 || now - start < 500000ULL);
126
+ }
127
+ return initstyle;
128
+ }
129
+
130
+ void
131
+ ulid_encode(char str[27], const unsigned char ulid[16])
132
+ {
133
+ static const char set[256] = {
134
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
135
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
136
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
137
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
138
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
139
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
140
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
141
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
142
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
143
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
144
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
145
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
146
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
147
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
148
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
149
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
150
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
151
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
152
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
153
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
154
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
155
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
156
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
157
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
158
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
159
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
160
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
161
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a,
162
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
163
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
164
+ 0x47, 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x51,
165
+ 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a
166
+ };
167
+ str[ 0] = set[ ulid[ 0] >> 5];
168
+ str[ 1] = set[ ulid[ 0] >> 0];
169
+ str[ 2] = set[ ulid[ 1] >> 3];
170
+ str[ 3] = set[(ulid[ 1] << 2 | ulid[ 2] >> 6) & 0x1f];
171
+ str[ 4] = set[ ulid[ 2] >> 1];
172
+ str[ 5] = set[(ulid[ 2] << 4 | ulid[ 3] >> 4) & 0x1f];
173
+ str[ 6] = set[(ulid[ 3] << 1 | ulid[ 4] >> 7) & 0x1f];
174
+ str[ 7] = set[ ulid[ 4] >> 2];
175
+ str[ 8] = set[(ulid[ 4] << 3 | ulid[ 5] >> 5) & 0x1f];
176
+ str[ 9] = set[ ulid[ 5] >> 0];
177
+ str[10] = set[ ulid[ 6] >> 3];
178
+ str[11] = set[(ulid[ 6] << 2 | ulid[ 7] >> 6) & 0x1f];
179
+ str[12] = set[ ulid[ 7] >> 1];
180
+ str[13] = set[(ulid[ 7] << 4 | ulid[ 8] >> 4) & 0x1f];
181
+ str[14] = set[(ulid[ 8] << 1 | ulid[ 9] >> 7) & 0x1f];
182
+ str[15] = set[ ulid[ 9] >> 2];
183
+ str[16] = set[(ulid[ 9] << 3 | ulid[10] >> 5) & 0x1f];
184
+ str[17] = set[ ulid[10] >> 0];
185
+ str[18] = set[ ulid[11] >> 3];
186
+ str[19] = set[(ulid[11] << 2 | ulid[12] >> 6) & 0x1f];
187
+ str[20] = set[ ulid[12] >> 1];
188
+ str[21] = set[(ulid[12] << 4 | ulid[13] >> 4) & 0x1f];
189
+ str[22] = set[(ulid[13] << 1 | ulid[14] >> 7) & 0x1f];
190
+ str[23] = set[ ulid[14] >> 2];
191
+ str[24] = set[(ulid[14] << 3 | ulid[15] >> 5) & 0x1f];
192
+ str[25] = set[ ulid[15] >> 0];
193
+ str[26] = 0;
194
+ }
195
+
196
+ int
197
+ ulid_decode(unsigned char ulid[16], const char *s)
198
+ {
199
+ static const signed char v[] = {
200
+ -1, -1, -1, -1, -1, -1, -1, -1,
201
+ -1, -1, -1, -1, -1, -1, -1, -1,
202
+ -1, -1, -1, -1, -1, -1, -1, -1,
203
+ -1, -1, -1, -1, -1, -1, -1, -1,
204
+ -1, -1, -1, -1, -1, -1, -1, -1,
205
+ -1, -1, -1, -1, -1, -1, -1, -1,
206
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
207
+ 0x08, 0x09, -1, -1, -1, -1, -1, -1,
208
+ -1, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
209
+ 0x11, 0x01, 0x12, 0x13, 0x01, 0x14, 0x15, 0x00,
210
+ 0x16, 0x17, 0x18, 0x19, 0x1a, -1, 0x1b, 0x1c,
211
+ 0x1d, 0x1e, 0x1f, -1, -1, -1, -1, -1,
212
+ -1, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
213
+ 0x11, 0x01, 0x12, 0x13, 0x01, 0x14, 0x15, 0x00,
214
+ 0x16, 0x17, 0x18, 0x19, 0x1a, -1, 0x1b, 0x1c,
215
+ 0x1d, 0x1e, 0x1f, -1, -1, -1, -1, -1,
216
+ -1, -1, -1, -1, -1, -1, -1, -1,
217
+ -1, -1, -1, -1, -1, -1, -1, -1,
218
+ -1, -1, -1, -1, -1, -1, -1, -1,
219
+ -1, -1, -1, -1, -1, -1, -1, -1,
220
+ -1, -1, -1, -1, -1, -1, -1, -1,
221
+ -1, -1, -1, -1, -1, -1, -1, -1,
222
+ -1, -1, -1, -1, -1, -1, -1, -1,
223
+ -1, -1, -1, -1, -1, -1, -1, -1,
224
+ -1, -1, -1, -1, -1, -1, -1, -1,
225
+ -1, -1, -1, -1, -1, -1, -1, -1,
226
+ -1, -1, -1, -1, -1, -1, -1, -1,
227
+ -1, -1, -1, -1, -1, -1, -1, -1,
228
+ -1, -1, -1, -1, -1, -1, -1, -1,
229
+ -1, -1, -1, -1, -1, -1, -1, -1,
230
+ -1, -1, -1, -1, -1, -1, -1, -1,
231
+ -1, -1, -1, -1, -1, -1, -1, -1
232
+ };
233
+ if (v[(int)s[0]] > 7)
234
+ return 1;
235
+ for (int i = 0; i < 26; i++)
236
+ if (v[(int)s[i]] == -1)
237
+ return 2;
238
+ ulid[ 0] = v[(int)s[ 0]] << 5 | v[(int)s[ 1]] >> 0;
239
+ ulid[ 1] = v[(int)s[ 2]] << 3 | v[(int)s[ 3]] >> 2;
240
+ ulid[ 2] = v[(int)s[ 3]] << 6 | v[(int)s[ 4]] << 1 | v[(int)s[ 5]] >> 4;
241
+ ulid[ 3] = v[(int)s[ 5]] << 4 | v[(int)s[ 6]] >> 1;
242
+ ulid[ 4] = v[(int)s[ 6]] << 7 | v[(int)s[ 7]] << 2 | v[(int)s[ 8]] >> 3;
243
+ ulid[ 5] = v[(int)s[ 8]] << 5 | v[(int)s[ 9]] >> 0;
244
+ ulid[ 6] = v[(int)s[10]] << 3 | v[(int)s[11]] >> 2;
245
+ ulid[ 7] = v[(int)s[11]] << 6 | v[(int)s[12]] << 1 | v[(int)s[13]] >> 4;
246
+ ulid[ 8] = v[(int)s[13]] << 4 | v[(int)s[14]] >> 1;
247
+ ulid[ 9] = v[(int)s[14]] << 7 | v[(int)s[15]] << 2 | v[(int)s[16]] >> 3;
248
+ ulid[10] = v[(int)s[16]] << 5 | v[(int)s[17]] >> 0;
249
+ ulid[11] = v[(int)s[18]] << 3 | v[(int)s[19]] >> 2;
250
+ ulid[12] = v[(int)s[19]] << 6 | v[(int)s[20]] << 1 | v[(int)s[21]] >> 4;
251
+ ulid[13] = v[(int)s[21]] << 4 | v[(int)s[22]] >> 1;
252
+ ulid[14] = v[(int)s[22]] << 7 | v[(int)s[23]] << 2 | v[(int)s[24]] >> 3;
253
+ ulid[15] = v[(int)s[24]] << 5 | v[(int)s[25]] >> 0;
254
+ return 0;
255
+ }
256
+
257
+ void
258
+ ulid_generate(struct ulid_generator *g, char str[27])
259
+ {
260
+ unsigned long long ts = platform_utime(1) / 1000;
261
+
262
+ if (!(g->flags & ULID_RELAXED) && g->last_ts == ts) {
263
+ /* Chance of 80-bit overflow is so small that it's not considered. */
264
+ for (int i = 15; i > 5; i--)
265
+ if (++g->last[i])
266
+ break;
267
+ ulid_encode(str, g->last);
268
+ return;
269
+ }
270
+
271
+ /* Fill out timestamp */
272
+ g->last_ts = ts;
273
+ g->last[0] = ts >> 40;
274
+ g->last[1] = ts >> 32;
275
+ g->last[2] = ts >> 24;
276
+ g->last[3] = ts >> 16;
277
+ g->last[4] = ts >> 8;
278
+ g->last[5] = ts >> 0;
279
+
280
+ /* Fill out random section */
281
+ for (int k = 0; k < 10; k++) {
282
+ g->i = (g->i + 1) & 0xff;
283
+ g->j = (g->j + g->s[g->i]) & 0xff;
284
+ int tmp = g->s[g->i];
285
+ g->s[g->i] = g->s[g->j];
286
+ g->s[g->j] = tmp;
287
+ g->last[6 + k] = g->s[(g->s[g->i] + g->s[g->j]) & 0xff];
288
+ }
289
+ if (g->flags & ULID_PARANOID)
290
+ g->last[6] &= 0x7f;
291
+
292
+ ulid_encode(str, g->last);
293
+ }
294
+
@@ -0,0 +1,59 @@
1
+ /* ULID generation and parsing library (API)
2
+ *
3
+ * This is free and unencumbered software released into the public domain.
4
+ */
5
+ #ifndef ULID_H
6
+ #define ULID_H
7
+
8
+ /* Generator configuration flags */
9
+ #define ULID_RELAXED (1 << 0)
10
+ #define ULID_PARANOID (1 << 1)
11
+ #define ULID_SECURE (1 << 2)
12
+
13
+ struct ulid_generator {
14
+ unsigned char last[16];
15
+ unsigned long long last_ts;
16
+ int flags;
17
+ unsigned char i, j;
18
+ unsigned char s[256];
19
+ };
20
+
21
+ /* Initialize a new ULID generator instance.
22
+ *
23
+ * The ULID_RELAXED flag allows ULIDs generated within the same
24
+ * millisecond to be non-monotonic, e.g. the random section is generated
25
+ * fresh each time.
26
+ *
27
+ * The ULID_PARANOID flag causes the generator to clear the highest bit
28
+ * of the random field, which guarantees that overflow cannot occur.
29
+ * Normally the chance of overflow is non-zero, but negligible. This
30
+ * makes it zero. It doesn't make sense to use this flag in conjunction
31
+ * with ULID_RELAX.
32
+ *
33
+ * The ULID_SECURE flag doesn't fall back on userspace initialization if
34
+ * system entropy could not be gathered. You _must_ check the return
35
+ * value if you use this flag, since it now indicates a hard error.
36
+ *
37
+ * Returns 0 if the generator was successfully initialized from secure
38
+ * system entropy. Returns 1 if this failed and instead derived entropy
39
+ * in userspace (or is uninitialized in the case of ULID_SECURE).
40
+ */
41
+ int ulid_generator_init(struct ulid_generator *, int flags);
42
+
43
+ /* Generate a new ULID.
44
+ * A zero terminating byte is written to the output buffer.
45
+ */
46
+ void ulid_generate(struct ulid_generator *, char [27]);
47
+
48
+ /* Encode a 128-bit binary ULID to its text format.
49
+ * A zero terminating byte is written to the output buffer.
50
+ */
51
+ void ulid_encode(char [27], const unsigned char [16]);
52
+
53
+ /* Decode a text ULID to a 128-bit binary ULID.
54
+ * Returns non-zero if input was invalid.
55
+ */
56
+ int ulid_decode(unsigned char [16], const char *);
57
+
58
+ #endif
59
+
@@ -0,0 +1,3 @@
1
+ module ULID
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ulid_fast
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Cook
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5'
41
+ description:
42
+ email:
43
+ executables: []
44
+ extensions:
45
+ - ext/ulid_fast/extconf.rb
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ext/ulid_fast/extconf.rb
49
+ - ext/ulid_fast/ulid-fast.c
50
+ - ext/ulid_fast/ulid.c
51
+ - ext/ulid_fast/ulid.h
52
+ - lib/ulid_fast/version.rb
53
+ homepage: https://github.com/jamescook/ulid_fast
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">"
64
+ - !ruby/object:Gem::Version
65
+ version: '2.1'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.1.2
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: ULID Ruby C Extension
76
+ test_files: []