• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

cmd/ulid/H09-May-2019-10791

vendor/github.com/pborman/getopt/H09-May-2019-7,9625,989

.gitignoreH A D09-May-2019329 3021

.travis.ymlH A D09-May-2019507 2120

AUTHORS.mdH A D09-May-201959 32

CHANGELOG.mdH A D09-May-2019695 3418

CONTRIBUTING.mdH A D09-May-2019770 1813

Gopkg.lockH A D09-May-2019433 1612

Gopkg.tomlH A D09-May-2019608 2723

LICENSEH A D09-May-201911.1 KiB202169

README.mdH A D09-May-20197.5 KiB183141

go.modH A D09-May-2019102 42

go.sumH A D09-May-2019225 32

ulid.goH A D09-May-201919.5 KiB629364

ulid_test.goH A D09-May-201918 KiB836691

README.md

1# Universally Unique Lexicographically Sortable Identifier
2
3![Project status](https://img.shields.io/badge/version-1.3.0-yellow.svg)
4[![Build Status](https://secure.travis-ci.org/oklog/ulid.png)](http://travis-ci.org/oklog/ulid)
5[![Go Report Card](https://goreportcard.com/badge/oklog/ulid?cache=0)](https://goreportcard.com/report/oklog/ulid)
6[![Coverage Status](https://coveralls.io/repos/github/oklog/ulid/badge.svg?branch=master&cache=0)](https://coveralls.io/github/oklog/ulid?branch=master)
7[![GoDoc](https://godoc.org/github.com/oklog/ulid?status.svg)](https://godoc.org/github.com/oklog/ulid)
8[![Apache 2 licensed](https://img.shields.io/badge/license-Apache2-blue.svg)](https://raw.githubusercontent.com/oklog/ulid/master/LICENSE)
9
10A Go port of [alizain/ulid](https://github.com/alizain/ulid) with binary format implemented.
11
12## Background
13
14A GUID/UUID can be suboptimal for many use-cases because:
15
16- It isn't the most character efficient way of encoding 128 bits
17- UUID v1/v2 is impractical in many environments, as it requires access to a unique, stable MAC address
18- UUID v3/v5 requires a unique seed and produces randomly distributed IDs, which can cause fragmentation in many data structures
19- UUID v4 provides no other information than randomness which can cause fragmentation in many data structures
20
21A ULID however:
22
23- Is compatible with UUID/GUID's
24- 1.21e+24 unique ULIDs per millisecond (1,208,925,819,614,629,174,706,176 to be exact)
25- Lexicographically sortable
26- Canonically encoded as a 26 character string, as opposed to the 36 character UUID
27- Uses Crockford's base32 for better efficiency and readability (5 bits per character)
28- Case insensitive
29- No special characters (URL safe)
30- Monotonic sort order (correctly detects and handles the same millisecond)
31
32## Install
33
34```shell
35go get github.com/oklog/ulid
36```
37
38## Usage
39
40An ULID is constructed with a `time.Time` and an `io.Reader` entropy source.
41This design allows for greater flexibility in choosing your trade-offs.
42
43Please note that `rand.Rand` from the `math` package is *not* safe for concurrent use.
44Instantiate one per long living go-routine or use a `sync.Pool` if you want to avoid the potential contention of a locked `rand.Source` as its been frequently observed in the package level functions.
45
46```go
47func ExampleULID() {
48	t := time.Unix(1000000, 0)
49	entropy := ulid.Monotonic(rand.New(rand.NewSource(t.UnixNano())), 0)
50	fmt.Println(ulid.MustNew(ulid.Timestamp(t), entropy))
51	// Output: 0000XSNJG0MQJHBF4QX1EFD6Y3
52}
53```
54
55## Commandline tool
56
57This repo also provides a tool to generate and parse ULIDs at the command line.
58
59Installation:
60
61```shell
62go get github.com/oklog/ulid/cmd/ulid
63```
64
65Usage:
66
67```shell
68Usage: ulid [-hlqz] [-f <format>] [parameters ...]
69 -f, --format=<format>  when parsing, show times in this format: default, rfc3339, unix, ms
70 -h, --help             print this help text
71 -l, --local            when parsing, show local time instead of UTC
72 -q, --quick            when generating, use non-crypto-grade entropy
73 -z, --zero             when generating, fix entropy to all-zeroes
74```
75
76Examples:
77
78```shell
79$ ulid
8001D78XYFJ1PRM1WPBCBT3VHMNV
81$ ulid -z
8201D78XZ44G0000000000000000
83$ ulid 01D78XZ44G0000000000000000
84Sun Mar 31 03:51:23.536 UTC 2019
85$ ulid --format=rfc3339 --local 01D78XZ44G0000000000000000
862019-03-30T20:51:23.536PDT
87```
88
89## Specification
90
91Below is the current specification of ULID as implemented in this repository.
92
93### Components
94
95**Timestamp**
96- 48 bits
97- UNIX-time in milliseconds
98- Won't run out of space till the year 10895 AD
99
100**Entropy**
101- 80 bits
102- User defined entropy source.
103- Monotonicity within the same millisecond with [`ulid.Monotonic`](https://godoc.org/github.com/oklog/ulid#Monotonic)
104
105### Encoding
106
107[Crockford's Base32](http://www.crockford.com/wrmg/base32.html) is used as shown.
108This alphabet excludes the letters I, L, O, and U to avoid confusion and abuse.
109
110```
1110123456789ABCDEFGHJKMNPQRSTVWXYZ
112```
113
114### Binary Layout and Byte Order
115
116The components are encoded as 16 octets. Each component is encoded with the Most Significant Byte first (network byte order).
117
118```
1190                   1                   2                   3
120 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
121+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122|                      32_bit_uint_time_high                    |
123+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124|     16_bit_uint_time_low      |       16_bit_uint_random      |
125+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126|                       32_bit_uint_random                      |
127+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128|                       32_bit_uint_random                      |
129+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130```
131
132### String Representation
133
134```
135 01AN4Z07BY      79KA1307SR9X4MV3
136|----------|    |----------------|
137 Timestamp           Entropy
138  10 chars           16 chars
139   48bits             80bits
140   base32             base32
141```
142
143## Test
144
145```shell
146go test ./...
147```
148
149## Benchmarks
150
151On a Intel Core i7 Ivy Bridge 2.7 GHz, MacOS 10.12.1 and Go 1.8.0beta1
152
153```
154BenchmarkNew/WithCryptoEntropy-8      2000000        771 ns/op      20.73 MB/s   16 B/op   1 allocs/op
155BenchmarkNew/WithEntropy-8            20000000      65.8 ns/op     243.01 MB/s   16 B/op   1 allocs/op
156BenchmarkNew/WithoutEntropy-8         50000000      30.0 ns/op     534.06 MB/s   16 B/op   1 allocs/op
157BenchmarkMustNew/WithCryptoEntropy-8  2000000        781 ns/op      20.48 MB/s   16 B/op   1 allocs/op
158BenchmarkMustNew/WithEntropy-8        20000000      70.0 ns/op     228.51 MB/s   16 B/op   1 allocs/op
159BenchmarkMustNew/WithoutEntropy-8     50000000      34.6 ns/op     462.98 MB/s   16 B/op   1 allocs/op
160BenchmarkParse-8                      50000000      30.0 ns/op     866.16 MB/s    0 B/op   0 allocs/op
161BenchmarkMustParse-8                  50000000      35.2 ns/op     738.94 MB/s    0 B/op   0 allocs/op
162BenchmarkString-8                     20000000      64.9 ns/op     246.40 MB/s   32 B/op   1 allocs/op
163BenchmarkMarshal/Text-8               20000000      55.8 ns/op     286.84 MB/s   32 B/op   1 allocs/op
164BenchmarkMarshal/TextTo-8             100000000     22.4 ns/op     714.91 MB/s    0 B/op   0 allocs/op
165BenchmarkMarshal/Binary-8             300000000     4.02 ns/op    3981.77 MB/s    0 B/op   0 allocs/op
166BenchmarkMarshal/BinaryTo-8           2000000000    1.18 ns/op   13551.75 MB/s    0 B/op   0 allocs/op
167BenchmarkUnmarshal/Text-8             100000000     20.5 ns/op    1265.27 MB/s    0 B/op   0 allocs/op
168BenchmarkUnmarshal/Binary-8           300000000     4.94 ns/op    3240.01 MB/s    0 B/op   0 allocs/op
169BenchmarkNow-8                        100000000     15.1 ns/op     528.09 MB/s    0 B/op   0 allocs/op
170BenchmarkTimestamp-8                  2000000000    0.29 ns/op   27271.59 MB/s    0 B/op   0 allocs/op
171BenchmarkTime-8                       2000000000    0.58 ns/op   13717.80 MB/s    0 B/op   0 allocs/op
172BenchmarkSetTime-8                    2000000000    0.89 ns/op    9023.95 MB/s    0 B/op   0 allocs/op
173BenchmarkEntropy-8                    200000000     7.62 ns/op    1311.66 MB/s    0 B/op   0 allocs/op
174BenchmarkSetEntropy-8                 2000000000    0.88 ns/op   11376.54 MB/s    0 B/op   0 allocs/op
175BenchmarkCompare-8                    200000000     7.34 ns/op    4359.23 MB/s    0 B/op   0 allocs/op
176```
177
178## Prior Art
179
180- [alizain/ulid](https://github.com/alizain/ulid)
181- [RobThree/NUlid](https://github.com/RobThree/NUlid)
182- [imdario/go-ulid](https://github.com/imdario/go-ulid)
183