Documentation
¶
Overview ¶
package zid provides some unique ID sources.
Throughout this package,
- Time precision depends on the time.Now
- Random value entropy depends on the rand.Reader
Random value sources are (cited from rand.Reader):
- On Linux, FreeBSD, Dragonfly, and Solaris, Reader uses getrandom(2).
- On legacy Linux (< 3.17), Reader opens /dev/urandom on first use.
- On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3).
- On NetBSD, Reader uses the kern.arandom sysctl.
- On Windows, Reader uses the ProcessPrng API.
- On js/wasm, Reader uses the Web Crypto API.
- On wasip1/wasm, Reader uses random_get.
References:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ContextWithID ¶
ContextWithID save an unique ID in the context with given key. A new context created with context.Background is used when nil context was given. Note that calling ContextWithID multiple times overwrites the existing unique ID. Use FromContext to extract stored id from the context.
Example ¶
package main
import (
"context"
"fmt"
"github.com/aileron-projects/go/zx/zuid"
)
func main() {
ctx := zuid.ContextWithID(context.Background(), "key", "example-unique-id")
uid := zuid.FromContext(ctx, "key")
fmt.Println(uid)
}
Output: example-unique-id
func FromContext ¶
FromContext returns an unique ID extracted from the context. Empty string will be returned if no unique ID found in the context or the context is nil. Use ContextWithID to save an id to the context.
func NewCount ¶
func NewCount() []byte
NewCount returns a new 30 bytes counter based ID. The returned ID is sortable by time, nearly has the same entropy as UUIDv4 and is hard to guess because of the random value. IDs are hard to duplicate but the possibility is not zero. The returned 30 bytes IDs do not contain any padding string when encoded with encoding/hex, encoding/base64 and encoding/base32.
ID consists of:
- 8 bytes unix time in microsecond. Valid until January 10th, 294247.
- 14 bytes random value read from crypto/rand.Reader.
- 8 bytes unsigned integer counter (reset to zero when overflow).
Bit arrangements:
0 1 2 3 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | counter_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | counter_middle | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | counter_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Encoded ID examples: (time:2000-01-01, random:12345678901234 counter:1)
- encoding/hex: 00035d013b37e00031323334353637383930313233340000000000000001
- encoding/base32.StdEncoding: AABV2AJ3G7QAAMJSGM2DKNRXHA4TAMJSGM2AAAAAAAAAAAAB
- encoding/base32.HexEncoding: 001LQ09R6VG00C9I6CQ3ADHN70SJ0C9I6CQ0000000000001
- encoding/base64.StdEncoding: AANdATs34AAxMjM0NTY3ODkwMTIzNAAAAAAAAAAB
- encoding/base64.URLEncoding: AANdATs34AAxMjM0NTY3ODkwMTIzNAAAAAAAAAAB
Example ¶
package main
import (
"encoding/base32"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/aileron-projects/go/zx/zuid"
)
func main() {
id := zuid.NewCount()
fmt.Println("Len :", len(id))
fmt.Println("hex :", hex.EncodeToString(id))
fmt.Println("base32.Std :", base32.StdEncoding.EncodeToString(id))
fmt.Println("base32.Hex :", base32.HexEncoding.EncodeToString(id))
fmt.Println("base64.Std :", base64.StdEncoding.EncodeToString(id))
fmt.Println("base64.URL :", base64.URLEncoding.EncodeToString(id))
}
func NewHost ¶
func NewHost() []byte
NewHost returns a new 30 bytes hostname based ID. The returned ID is sortable by time, nearly has the same entropy as UUIDv4 and is hard to guess because of the random value. IDs are hard to duplicate but the possibility is not zero. The returned 30 bytes IDs do not contain any padding string when encoded with encoding/hex, encoding/base64 and encoding/base32.
ID consists of:
- 8 bytes unix time in microsecond. Valid until January 10th, 294247.
- 8 bytes FNV1a/64 hash of the hostname.
- 14 bytes random value read from crypto/rand.Reader.
Bit arrangements:
0 1 2 3 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | FNV1a/64(hostname)_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | FNV1a/64(hostname)_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Encoded ID examples: (time:2000-01-01, random:12345678901234 hostFNV:host1234)
- encoding/hex: 00035d013b37e000686f7374313233343132333435363738393031323334
- encoding/base32.StdEncoding: AABV2AJ3G7QAA2DPON2DCMRTGQYTEMZUGU3DOOBZGAYTEMZU
- encoding/base32.HexEncoding: 001LQ09R6VG00Q3FEDQ32CHJ6GOJ4CPK6KR3EE1P60OJ4CPK
- encoding/base64.StdEncoding: AANdATs34ABob3N0MTIzNDEyMzQ1Njc4OTAxMjM0
- encoding/base64.URLEncoding: AANdATs34ABob3N0MTIzNDEyMzQ1Njc4OTAxMjM0
Encoding the returned ID will results in the following pattern:
- Base16 : ^[0-9a-fA-F]{60}$
- Base32 : ^[2-7A-Z]{48}$
- Base32Hex : ^[0-9A-V]{48}$
- Base64 : ^[0-9a-zA-Z+/]{40}$
- Base64Raw : ^[0-9a-zA-Z+/]{40}$
- Base64URL : ^[0-9a-zA-Z-_]{40}$
- Base64RawURL : ^[0-9a-zA-Z-_]{40}$
Example ¶
package main
import (
"encoding/base32"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/aileron-projects/go/zx/zuid"
)
func main() {
id := zuid.NewHost()
fmt.Println("Len :", len(id))
fmt.Println("hex :", hex.EncodeToString(id))
fmt.Println("base32.Std :", base32.StdEncoding.EncodeToString(id))
fmt.Println("base32.Hex :", base32.HexEncoding.EncodeToString(id))
fmt.Println("base64.Std :", base64.StdEncoding.EncodeToString(id))
fmt.Println("base64.URL :", base64.URLEncoding.EncodeToString(id))
}
func NewTime ¶
func NewTime() []byte
NewTime returns a new 30 bytes timestamp based ID. The returned ID is sortable by time, higher entropy than UUIDv4 and is hard to guess because of the random value. IDs are hard to duplicate but the possibility is not zero. The returned 30 bytes IDs do not contain any padding string when encoded with encoding/hex, encoding/base64 and encoding/base32.
ID consists of:
- 8 bytes unix time in microsecond. Valid until January 10th, 294247.
- 22 bytes random value read from crypto/rand.Reader.
Bit arrangements:
0 1 2 3 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_high | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | timestamp_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | random | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Encoded ID examples: (time:2000-01-01, random:1234567890123456789012)
- encoding/hex: 00035d013b37e00031323334353637383930313233343536373839303132
- encoding/base32.StdEncoding: AABV2AJ3G7QAAMJSGM2DKNRXHA4TAMJSGM2DKNRXHA4TAMJS
- encoding/base32.HexEncoding: 001LQ09R6VG00C9I6CQ3ADHN70SJ0C9I6CQ3ADHN70SJ0C9I
- encoding/base64.StdEncoding: AANdATs34AAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEy
- encoding/base64.URLEncoding: AANdATs34AAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEy
Encoding the returned ID will results in the following pattern:
- Base16 : ^[0-9a-fA-F]{60}$
- Base32 : ^[2-7A-Z]{48}$
- Base32Hex : ^[0-9A-V]{48}$
- Base64 : ^[0-9a-zA-Z+/]{40}$
- Base64Raw : ^[0-9a-zA-Z+/]{40}$
- Base64URL : ^[0-9a-zA-Z-_]{40}$
- Base64RawURL : ^[0-9a-zA-Z-_]{40}$
Example ¶
package main
import (
"encoding/base32"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/aileron-projects/go/zx/zuid"
)
func main() {
id := zuid.NewTime()
fmt.Println("Len :", len(id))
fmt.Println("hex :", hex.EncodeToString(id))
fmt.Println("base32.Std :", base32.StdEncoding.EncodeToString(id))
fmt.Println("base32.Hex :", base32.HexEncoding.EncodeToString(id))
fmt.Println("base64.Std :", base64.StdEncoding.EncodeToString(id))
fmt.Println("base64.URL :", base64.URLEncoding.EncodeToString(id))
}
Types ¶
This section is empty.