As described in theulidspecification repo, and slightly edited here, UUID use can besuboptimal for many uses-cases because:
Instead, an alternative is proposed in ULID:
ulid()// 01ARZ3NDEKTSV4RRFFQ69G5FAVwith the following properties:
01AN4Z07BY 79KA1307SR9X4MV3|----------| |----------------| Timestamp Randomness 48bits 80bitsTimestamp
Randomness
The left-most character must be sorted first, and the right-mostcharacter sorted last (lexical order). The default ASCII character setmust be used. Within the same millisecond, sort order is notguaranteed.
The following functions are implemented:
ts_generate: Generate ULIDs from timestampsULIDgenerate: Generate ULIDsunmarshal: Unmarshal a ULID into a data frame withtimestamp and random bitstring columnsulid: Alias forULIDgenerateThe package can be installed fromCRAN viainstall.packages("ulid"). Development versions can also beinstalled from this repository or fromr-universe via
r<-c('https://eddelbuettel.r-universe.dev','https://cloud.r-project.org')install.packages('ulid',repos = r)ulid::ULIDgenerate()## [1] "0001EKRGEEV98QP062VNRX31P2"(u<- ulid::ULIDgenerate(20))## [1] "0001EKRGEEV5XMP54RRRWAK318" "0001EKRGEEKX7VC0PF75AZJXHP"## [3] "0001EKRGEEXENNCQEH4KCH8QAD" "0001EKRGEEY41HJ6GMXRV1BQBA"## [5] "0001EKRGEE6HVD7ACWZ52MTVCJ" "0001EKRGEEQWXMPXGC0DGQN32B"## [7] "0001EKRGEE6W13BK92EF1RXYT7" "0001EKRGEE5A31H38NJFGTK8PC"## [9] "0001EKRGEEG2GXS53QY9F3M0A9" "0001EKRGEEDA3Y6Y0T52WTS6RM"## [11] "0001EKRGEE5WS2S3D9KY3F5H9Y" "0001EKRGEE24SZW5NATAADAY9Q"## [13] "0001EKRGEEBEG51QCKXPM8ZS16" "0001EKRGEE1ZC1QY7RCJR9VJ0B"## [15] "0001EKRGEECJ50Z4FXM4HW6XWG" "0001EKRGEEER84JP8WTXV5DWV8"## [17] "0001EKRGEEW3ABA82GZSRXN1RB" "0001EKRGEEAA60CYFGR8832JD6"## [19] "0001EKRGEE6W5ARCFHH6T75FPZ" "0001EKRGEE5WT4XNP7NS69BM3X"unmarshal(u)## ts rnd## 1 2019-07-27 08:21:34 V5XMP54RRRWAK318## 2 2019-07-27 08:21:34 KX7VC0PF75AZJXHP## 3 2019-07-27 08:21:34 XENNCQEH4KCH8QAD## 4 2019-07-27 08:21:34 Y41HJ6GMXRV1BQBA## 5 2019-07-27 08:21:34 6HVD7ACWZ52MTVCJ## 6 2019-07-27 08:21:34 QWXMPXGC0DGQN32B## 7 2019-07-27 08:21:34 6W13BK92EF1RXYT7## 8 2019-07-27 08:21:34 5A31H38NJFGTK8PC## 9 2019-07-27 08:21:34 G2GXS53QY9F3M0A9## 10 2019-07-27 08:21:34 DA3Y6Y0T52WTS6RM## 11 2019-07-27 08:21:34 5WS2S3D9KY3F5H9Y## 12 2019-07-27 08:21:34 24SZW5NATAADAY9Q## 13 2019-07-27 08:21:34 BEG51QCKXPM8ZS16## 14 2019-07-27 08:21:34 1ZC1QY7RCJR9VJ0B## 15 2019-07-27 08:21:34 CJ50Z4FXM4HW6XWG## 16 2019-07-27 08:21:34 ER84JP8WTXV5DWV8## 17 2019-07-27 08:21:34 W3ABA82GZSRXN1RB## 18 2019-07-27 08:21:34 AA60CYFGR8832JD6## 19 2019-07-27 08:21:34 6W5ARCFHH6T75FPZ## 20 2019-07-27 08:21:34 5WT4XNP7NS69BM3X(ut<-ts_generate(as.POSIXct("2017-11-01 15:00:00",origin="1970-01-01")))## [1] "0001CZM6DG2THKSAX3F1SF30E7"unmarshal(ut)## ts rnd## 1 2017-11-01 15:00:00 2THKSAX3F1SF30E7As perissuetime_t leading to second rather than millisecondresolution. Two patches by Chris Brove also collected inhis fork improve on this byusingstd::chrono objects internally. In release 0.4.0, wehave switches to his fork and extended the wrapper functions to supportthis:
>library(ulid)> gen_ulid<- \(sleep)replicate(5, {Sys.sleep(sleep);generate()})> u<-gen_ulid(.1)> df<-unmarshal(u)> data.table::data.table(df) ts rnd<POSc><char>1:2024-05-3016:38:28.588 CSQAJBPNX75R0G5A2:2024-05-3016:38:28.688 XZX0TREDHD6PC1YR3:2024-05-3016:38:28.789 0YK9GKZVTED27QMK4:2024-05-3016:38:28.890 SC3M3G6KGPH7S50S5:2024-05-3016:38:28.990 TSKCBWJ3TEKCPBY0>Suyash Verma wrote the C++header libraryulid.
Chris Bove updatedinternals to permit sub-second resolution in hisfork.
Bob Rudis created the R package,prepared versions 0.1.0 and 0.2.0, and released version 0.3.0 toCRAN.
Dirk Eddelbuettel hasbeen maintainer since release 0.3.1.
The package is licensed under the MIT License
Initially created: Tue Apr 2 08:14:25 AM CDT 2024
Last modified: Tue Jun 04 07:55:32 CDT 2024