Module: FastCuid2
- Defined in:
- lib/gem/fast_cuid2.rb,
lib/gem/fast_cuid2/version.rb,
ext/fast_cuid2/fast_cuid2.c
Defined Under Namespace
Classes: Error
Constant Summary collapse
- VERSION =
'1.0.0'
Class Method Summary collapse
-
.generate ⇒ String
Generates a CUID2 (Collision-resistant Unique IDentifier).
-
.valid?(str) ⇒ Boolean
Validates a CUID2 string.
Class Method Details
.generate ⇒ String
Generates a CUID2 (Collision-resistant Unique IDentifier). Format: <6 chars timestamp><18 chars random>
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 |
# File 'ext/fast_cuid2/fast_cuid2.c', line 63
static VALUE rb_generate_cuid2(VALUE self) {
char cuid[CUID2_BUFFER_SIZE] = {0};
struct timespec ts;
unsigned char random_bytes[RANDOM_BYTES_LENGTH];
// Get current timestamp in milliseconds
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
rb_raise(rb_eRuntimeError, "Failed to get system time");
}
uint64_t timestamp = (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
// Generate random bytes
generate_random_bytes(random_bytes, RANDOM_BYTES_LENGTH);
// Encode timestamp (first 6 chars)
encode_base32(timestamp, cuid, TIMESTAMP_LENGTH);
// Fill remaining 18 chars with random data
// Process 2 bytes at a time to generate 3 base32 chars
for (int i = 0; i < RANDOM_BYTES_LENGTH; i += RANDOM_CHUNK_SIZE) {
uint32_t rand_chunk =
((uint32_t)random_bytes[i] << 8) |
((uint32_t)random_bytes[i + 1]);
encode_base32(rand_chunk, cuid + TIMESTAMP_LENGTH + (i / RANDOM_CHUNK_SIZE) * BASE32_CHARS_PER_CHUNK, BASE32_CHARS_PER_CHUNK);
}
ensure_first_char_is_letter(cuid);
return rb_str_new2(cuid);
}
|
.valid?(str) ⇒ Boolean
Validates a CUID2 string.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'ext/fast_cuid2/fast_cuid2.c', line 99
static VALUE rb_validate_cuid2(VALUE self, VALUE str) {
Check_Type(str, T_STRING);
if (RSTRING_LEN(str) != CUID2_LENGTH) return Qfalse;
const char *cuid = StringValuePtr(str);
for (int i = 0; i < CUID2_LENGTH; i++) {
if (!strchr(BASE32_CHARS, cuid[i])) return Qfalse;
}
// First character must be a letter
if (strchr("0123456789", cuid[0])) return Qfalse;
return Qtrue;
}
|