21 void EncodeTime(time_t timestamp,
ULID& ulid) {
22 ULID t =
static_cast<uint8_t>(timestamp >> 40);
25 t |=
static_cast<uint8_t>(timestamp >> 32);
28 t |=
static_cast<uint8_t>(timestamp >> 24);
31 t |=
static_cast<uint8_t>(timestamp >> 16);
34 t |=
static_cast<uint8_t>(timestamp >> 8);
37 t |=
static_cast<uint8_t>(timestamp);
45 ulid = t | (ulid & mask);
51 void EncodeTimeNow(
ULID& ulid) {
52 EncodeTime(std::time(
nullptr), ulid);
59 void EncodeTimeSystemClockNow(
ULID& ulid) {
60 auto now = std::chrono::system_clock::now();
61 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
62 EncodeTime(ms.count(), ulid);
69 void EncodeEntropy(
const std::function<uint8_t()>& rng,
ULID& ulid) {
70 ulid = (ulid >> 80) << 80;
109 void EncodeEntropyRand(
ULID& ulid) {
110 ulid = (ulid >> 80) << 80;
112 ULID e = (std::rand() * 255ull) / RAND_MAX;
115 e |= (std::rand() * 255ull) / RAND_MAX;
118 e |= (std::rand() * 255ull) / RAND_MAX;
121 e |= (std::rand() * 255ull) / RAND_MAX;
124 e |= (std::rand() * 255ull) / RAND_MAX;
127 e |= (std::rand() * 255ull) / RAND_MAX;
130 e |= (std::rand() * 255ull) / RAND_MAX;
133 e |= (std::rand() * 255ull) / RAND_MAX;
136 e |= (std::rand() * 255ull) / RAND_MAX;
139 e |= (std::rand() * 255ull) / RAND_MAX;
151 void EncodeEntropyMt19937(std::mt19937& generator,
ULID& ulid) {
152 ulid = (ulid >> 80) << 80;
189 void Encode(time_t timestamp,
const std::function<uint8_t()>& rng,
ULID& ulid) {
190 EncodeTime(timestamp, ulid);
191 EncodeEntropy(rng, ulid);
197 void EncodeNowRand(
ULID& ulid) {
199 EncodeEntropyRand(ulid);
205 ULID Create(time_t timestamp,
const std::function<uint8_t()>& rng) {
207 Encode(timestamp, rng, ulid);
223 const char Encoding[33] =
"0123456789ABCDEFGHJKMNPQRSTVWXYZ";
246 void MarshalTo(
const ULID& ulid,
char dst[26]) {
248 dst[0] = Encoding[(
static_cast<uint8_t>(ulid >> 120) & 224) >> 5];
249 dst[1] = Encoding[
static_cast<uint8_t>(ulid >> 120) & 31];
250 dst[2] = Encoding[(
static_cast<uint8_t>(ulid >> 112) & 248) >> 3];
251 dst[3] = Encoding[((
static_cast<uint8_t>(ulid >> 112) & 7) << 2) | ((
static_cast<uint8_t>(ulid >> 104) & 192) >> 6)];
252 dst[4] = Encoding[(
static_cast<uint8_t>(ulid >> 104) & 62) >> 1];
253 dst[5] = Encoding[((
static_cast<uint8_t>(ulid >> 104) & 1) << 4) | ((
static_cast<uint8_t>(ulid >> 96) & 240) >> 4)];
254 dst[6] = Encoding[((
static_cast<uint8_t>(ulid >> 96) & 15) << 1) | ((
static_cast<uint8_t>(ulid >> 88) & 128) >> 7)];
255 dst[7] = Encoding[(
static_cast<uint8_t>(ulid >> 88) & 124) >> 2];
256 dst[8] = Encoding[((
static_cast<uint8_t>(ulid >> 88) & 3) << 3) | ((
static_cast<uint8_t>(ulid >> 80) & 224) >> 5)];
257 dst[9] = Encoding[
static_cast<uint8_t>(ulid >> 80) & 31];
260 dst[10] = Encoding[(
static_cast<uint8_t>(ulid >> 72) & 248) >> 3];
261 dst[11] = Encoding[((
static_cast<uint8_t>(ulid >> 72) & 7) << 2) | ((
static_cast<uint8_t>(ulid >> 64) & 192) >> 6)];
262 dst[12] = Encoding[(
static_cast<uint8_t>(ulid >> 64) & 62) >> 1];
263 dst[13] = Encoding[((
static_cast<uint8_t>(ulid >> 64) & 1) << 4) | ((
static_cast<uint8_t>(ulid >> 56) & 240) >> 4)];
264 dst[14] = Encoding[((
static_cast<uint8_t>(ulid >> 56) & 15) << 1) | ((
static_cast<uint8_t>(ulid >> 48) & 128) >> 7)];
265 dst[15] = Encoding[(
static_cast<uint8_t>(ulid >> 48) & 124) >> 2];
266 dst[16] = Encoding[((
static_cast<uint8_t>(ulid >> 48) & 3) << 3) | ((
static_cast<uint8_t>(ulid >> 40) & 224) >> 5)];
267 dst[17] = Encoding[
static_cast<uint8_t>(ulid >> 40) & 31];
268 dst[18] = Encoding[(
static_cast<uint8_t>(ulid >> 32) & 248) >> 3];
269 dst[19] = Encoding[((
static_cast<uint8_t>(ulid >> 32) & 7) << 2) | ((
static_cast<uint8_t>(ulid >> 24) & 192) >> 6)];
270 dst[20] = Encoding[(
static_cast<uint8_t>(ulid >> 24) & 62) >> 1];
271 dst[21] = Encoding[((
static_cast<uint8_t>(ulid >> 24) & 1) << 4) | ((
static_cast<uint8_t>(ulid >> 16) & 240) >> 4)];
272 dst[22] = Encoding[((
static_cast<uint8_t>(ulid >> 16) & 15) << 1) | ((
static_cast<uint8_t>(ulid >> 8) & 128) >> 7)];
273 dst[23] = Encoding[(
static_cast<uint8_t>(ulid >> 8) & 124) >> 2];
274 dst[24] = Encoding[((
static_cast<uint8_t>(ulid >> 8) & 3) << 3) | (((
static_cast<uint8_t>(ulid)) & 224) >> 5)];
275 dst[25] = Encoding[(
static_cast<uint8_t>(ulid)) & 31];
281 std::string Marshal(
const ULID& ulid) {
284 MarshalTo(ulid, data);
285 return std::string(data);
291 void MarshalBinaryTo(
const ULID& ulid, uint8_t dst[16]) {
293 dst[0] =
static_cast<uint8_t>(ulid >> 120);
294 dst[1] =
static_cast<uint8_t>(ulid >> 112);
295 dst[2] =
static_cast<uint8_t>(ulid >> 104);
296 dst[3] =
static_cast<uint8_t>(ulid >> 96);
297 dst[4] =
static_cast<uint8_t>(ulid >> 88);
298 dst[5] =
static_cast<uint8_t>(ulid >> 80);
301 dst[6] =
static_cast<uint8_t>(ulid >> 72);
302 dst[7] =
static_cast<uint8_t>(ulid >> 64);
303 dst[8] =
static_cast<uint8_t>(ulid >> 56);
304 dst[9] =
static_cast<uint8_t>(ulid >> 48);
305 dst[10] =
static_cast<uint8_t>(ulid >> 40);
306 dst[11] =
static_cast<uint8_t>(ulid >> 32);
307 dst[12] =
static_cast<uint8_t>(ulid >> 24);
308 dst[13] =
static_cast<uint8_t>(ulid >> 16);
309 dst[14] =
static_cast<uint8_t>(ulid >> 8);
310 dst[15] =
static_cast<uint8_t>(ulid);
316 std::vector<uint8_t> MarshalBinary(
const ULID& ulid) {
317 std::vector<uint8_t> dst(16);
318 MarshalBinaryTo(ulid, dst.data());
328 const uint8_t dec[256] = {
329 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
330 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
331 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
332 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
334 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
335 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
337 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
339 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
342 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
344 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
346 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
348 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
350 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
351 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
352 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
353 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
355 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
356 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
357 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
358 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
360 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
361 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
362 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
363 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
365 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
366 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
367 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
368 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
370 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
371 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
372 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
373 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
379 void UnmarshalFrom(
const char str[26],
ULID& ulid) {
381 ulid = (dec[
int(str[0])] << 5) | dec[
int(str[1])];
384 ulid |= (dec[
int(str[2])] << 3) | (dec[
int(str[3])] >> 2);
387 ulid |= (dec[
int(str[3])] << 6) | (dec[
int(str[4])] << 1) | (dec[
int(str[5])] >> 4);
390 ulid |= (dec[
int(str[5])] << 4) | (dec[
int(str[6])] >> 1);
393 ulid |= (dec[
int(str[6])] << 7) | (dec[
int(str[7])] << 2) | (dec[
int(str[8])] >> 3);
396 ulid |= (dec[
int(str[8])] << 5) | dec[
int(str[9])];
400 ulid |= (dec[
int(str[10])] << 3) | (dec[
int(str[11])] >> 2);
403 ulid |= (dec[
int(str[11])] << 6) | (dec[
int(str[12])] << 1) | (dec[
int(str[13])] >> 4);
406 ulid |= (dec[
int(str[13])] << 4) | (dec[
int(str[14])] >> 1);
409 ulid |= (dec[
int(str[14])] << 7) | (dec[
int(str[15])] << 2) | (dec[
int(str[16])] >> 3);
412 ulid |= (dec[
int(str[16])] << 5) | dec[
int(str[17])];
415 ulid |= (dec[
int(str[18])] << 3) | (dec[
int(str[19])] >> 2);
418 ulid |= (dec[
int(str[19])] << 6) | (dec[
int(str[20])] << 1) | (dec[
int(str[21])] >> 4);
421 ulid |= (dec[
int(str[21])] << 4) | (dec[
int(str[22])] >> 1);
424 ulid |= (dec[
int(str[22])] << 7) | (dec[
int(str[23])] << 2) | (dec[
int(str[24])] >> 3);
427 ulid |= (dec[
int(str[24])] << 5) | dec[
int(str[25])];
435 UnmarshalFrom(str.c_str(), ulid);
442 void UnmarshalBinaryFrom(
const uint8_t b[16],
ULID& ulid) {
498 UnmarshalBinaryFrom(b.data(), ulid);
509 int CompareULIDs(
const ULID& ulid1,
const ULID& ulid2) {
510 return -2 * (ulid1 < ulid2) - 1 * (ulid1 == ulid2) + 1;
516 time_t Time(
const ULID& ulid) {
519 ans |=
static_cast<uint8_t>(ulid >> 120);
522 ans |=
static_cast<uint8_t>(ulid >> 112);
525 ans |=
static_cast<uint8_t>(ulid >> 104);
528 ans |=
static_cast<uint8_t>(ulid >> 96);
531 ans |=
static_cast<uint8_t>(ulid >> 88);
534 ans |=
static_cast<uint8_t>(ulid >> 80);
ULID UnmarshalBinary(const std::vector< uint8_t > &b)
Definition: ulid_struct.hh:584
ULID CreateNowRand()
Definition: ulid_struct.hh:360
std::uniform_int_distribution< uint8_t > Distribution_0_255(0, 255)
Definition: ulid_struct.hh:10
ULID Create(time_t timestamp, const std::function< uint8_t()> &rng)
Definition: ulid_struct.hh:351
__uint128_t ULID
Definition: ulid_uint128.hh:15
ULID Unmarshal(const std::string &str)
Definition: ulid_struct.hh:550