mtime_to_uuidv7.c (1555B)
1 #include <stdint.h> 2 #include <sys/stat.h> /* for stat(), struct stat */ 3 #include <unistd.h> /* for getentropy() */ 4 #include <stdio.h> /* for printf() */ 5 #include <fcntl.h> /* Definition of AT_* constants */ 6 7 #include <skalibs/strerr.h> 8 9 #define PROG "mtime_to_uuidv7" 10 #define USAGE "mtime_to_uuidv7 [filename]" 11 12 13 void uuidv7(struct timespec *ts, uint8_t* value) { 14 // timestamp in ms 15 uint64_t timestamp = (uint64_t)ts->tv_sec * 1000 + ts->tv_nsec / 1000000; 16 17 // random bytes 18 if(getentropy(value, 16)) { 19 strerr_dief1sys(111, "getentropy()"); 20 } 21 22 // timestamp 23 value[0] = (timestamp >> 40) & 0xFF; 24 value[1] = (timestamp >> 32) & 0xFF; 25 value[2] = (timestamp >> 24) & 0xFF; 26 value[3] = (timestamp >> 16) & 0xFF; 27 value[4] = (timestamp >> 8) & 0xFF; 28 value[5] = timestamp & 0xFF; 29 30 // version and variant 31 value[6] = (value[6] & 0x0F) | 0x70; 32 value[8] = (value[8] & 0x3F) | 0x80; 33 } 34 35 36 int main (int argc, char const *const *argv) 37 { 38 if (argc > 2) { 39 strerr_dieusage(100, USAGE); 40 } 41 struct stat statinfo; 42 if(argc == 2) { 43 if(stat(argv[1], &statinfo)) { 44 strerr_diefu2sys(111, "stat(): ", argv[1]); 45 } 46 } else { 47 if(fstatat(0, "", &statinfo, AT_EMPTY_PATH)) { 48 strerr_diefu1sys(111, "fstatat(stdin)"); 49 } 50 } 51 52 uint8_t uuid_val[16]; 53 uuidv7(&statinfo.st_mtim, uuid_val); 54 55 for (size_t i = 0; i < 16; i++) { 56 printf("%02x", uuid_val[i]); 57 } 58 printf("\n"); 59 60 return 0; 61 } 62 /* vim: sw=4 sts=4 et 63 */