Help us shape the future of Go! Take the 2026 Go Developer Survey

uidgen

package
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package uidgen 提供分布式唯一 ID 生成器.

推荐使用 Snowflake(全局单例 + 极简 API):

uidgen.InitSnowflake(7)                  // 一次性初始化, machineID ∈ [0, 1023]
id := uidgen.SnowflakeID()               // int64, 不返错, auto-init 兜底
uidgen.ExtractSnowflakeTime(id)          // epoch = 2026-01-01
uidgen.ExtractSnowflakeMachineID(id)
uidgen.ExtractSnowflakeSequence(id)

Extract 函数(epoch = 2024-01-01)用于从旧式 ID 中提取元数据:

uidgen.ExtractTime(id)
uidgen.ExtractWorkerID(id)
uidgen.ExtractSequence(id)

UUID 系列(与 Snowflake 无关)见 uuid.go.

ULID 系列(26 字符,字典序 == 时间序)见 ulid.go——面向「文本主键 + 按 ID 做时间序 range scan」的场景:

id := uidgen.ULID()                       // 26 字符,同毫秒内严格递增
uidgen.ULIDFromTime(t)                   // 指定时间戳(按业务时间回填)
ts, entropy, err := uidgen.ParseULID(id)  // 解回时间戳与 80 bit 熵

crypto/rand 随机串生成(标识符/密钥面):与 Snowflake(可预测、仅作 ID)分居—— 密钥、一次性凭据、高熵标识符必须走本文件。

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidULID = errors.New("uidgen: invalid ULID")

ErrInvalidULID 表示字符串不是合法 ULID:长度不对、含非法字符, 或超出 128 bit 范围(首字符取值大于 '7')。

调用方用 errors.Is(err, uidgen.ErrInvalidULID) 判定;具体原因在错误消息里。

Functions

func ExtractSequence

func ExtractSequence(id int64) int64

ExtractSequence 从 ID 中提取序列号。

func ExtractSnowflakeMachineID

func ExtractSnowflakeMachineID(id int64) int64

ExtractSnowflakeMachineID 从 Snowflake ID 中提取 machineID.

func ExtractSnowflakeSequence

func ExtractSnowflakeSequence(id int64) int64

ExtractSnowflakeSequence 从 Snowflake ID 中提取 sequence.

func ExtractSnowflakeTime

func ExtractSnowflakeTime(id int64) time.Time

ExtractSnowflakeTime 从 Snowflake ID 中提取生成时间. 注意:与 ExtractTime 不可混用——epoch 不同(2026 vs 2024).

func ExtractTime

func ExtractTime(id int64) time.Time

ExtractTime 从 ID 中提取生成时间。

func ExtractWorkerID

func ExtractWorkerID(id int64) int64

ExtractWorkerID 从 ID 中提取 workerID。

func InitSnowflake

func InitSnowflake(machineID int64) error

InitSnowflake 初始化全局 Snowflake singleton. machineID 必须在 [0, 1023] 范围. 多次调用:第一次生效,后续返错(防止误用).

并发安全:CAS(nil -> s) 失败表示已初始化,Load() 拿到的是上次成功的实例.

func InitSnowflakeFromEnv

func InitSnowflakeFromEnv() error

InitSnowflakeFromEnv 从 MACHINE_ID env 读 machineID,解析失败兜底 0. 单进程 dev / 测试默认 0 够用;生产必须显式注入(e.g. docker-compose 配 0/1/2).

func ParseULID added in v0.3.0

func ParseULID(s string) (time.Time, []byte, error)

ParseULID 解析 ULID,返回它的毫秒时间戳与 80 bit 熵(10 字节)。

大小写不敏感(ULID 规范如此)。长度不对、含非法字符、或超出 128 bit (首字符取值大于 '7')时返回包装了 ErrInvalidULID 的错误。

func RandomHex

func RandomHex(nBytes int) string

RandomHex n 字节 crypto/rand 随机数的十六进制串(2n 字符)。n<=0 返回空串。 适用:对象 ID、webhook secret 等高熵标识符。

func RandomString

func RandomString(alphabet string, n int) string

RandomString 从 alphabet 均匀采样 n 个字符(拒绝采样消模偏差,无 mod 偏置)。 alphabet 为空时 panic。适用:带自定义字符集的短 ID/令牌。

func ShortUUID

func ShortUUID() string

ShortUUID 返回一个 16 位的短 UUID。

func ShortUUIDToUpper

func ShortUUIDToUpper() string

ShortUUIDToUpper 返回大写的 16 位短 UUID。

func SnowflakeID

func SnowflakeID() int64

SnowflakeID 拿下一个 int64 ID. 未 InitSnowflake 时自动以 machineID=0 初始化.

并发说明:auto-init 路径在多 goroutine 同时首次调用时,CAS 失败的 goroutine 会回退到 Load() 读已 init 的实例,保证不会 nil deref.

时钟回拨:阻塞等直到时间追平,不返错. 业务层应监控回拨时长,超过阈值告警.

func SnowflakeMachineID

func SnowflakeMachineID() int64

SnowflakeMachineID 返当前 init 用的 machine ID,未初始化返 -1,测试用.

func ULID added in v0.3.0

func ULID() string

ULID 返回 26 字符的 ULID(Universally Unique Lexicographically Sortable Identifier)。

结构 = 48 bit 毫秒时间戳(Unix 纪元)+ 80 bit 熵,Crockford Base32 编码。 适用于「文本主键 + 按 ID 做时间序 range scan」这一类需求: Snowflake 是 int64(不能直接当文本主键),UUID 是随机串(字典序与时间无关)。

同一毫秒内进程内**严格单调**:熵逐个递增,80 bit 熵用尽则进位到下一毫秒。 时钟回拨时冻结在上一次的毫秒继续递增熵,保证不会出现更小的 ID。

零第三方依赖:crypto/rand + 标准库。

func ULIDFromTime added in v0.3.0

func ULIDFromTime(t time.Time) string

ULIDFromTime 用指定时间戳生成 ULID,便于按业务时间回填 ID。

时间戳取 t 的 Unix 毫秒;熵为随机值。**不参与 ULID() 的进程内单调序列** ——回填的业务时间可能早于当前时间,混进单调序列会破坏它的单调性。 同一 t 多次调用得到的 ULID 彼此无序,需要有序时请用 ULID()。

t 超出 48 bit 毫秒时间戳范围(Unix 纪元之前,或公元 10889 年之后)时 panic: 这种时间戳编不出合法 ULID,静默截断会得到一个「时间不对但看着正常」的 ID。

func UUID

func UUID() string

UUID 返回一个不带连字符的 UUID 字符串。

func UUIDToUpper

func UUIDToUpper() string

UUIDToUpper 返回大写的 UUID 字符串。

func UUIDWithHyphen

func UUIDWithHyphen() string

UUIDWithHyphen 返回带连字符的 UUID 字符串。

Types

type Snowflake

type Snowflake struct {
	// contains filtered or unexported fields
}

Snowflake 是 singleton 模式的 Snowflake ID 生成器.

Bit 布局(bit 63 → 0):

[1 sign | 41 ts | 10 machine | 12 sequence]

= ~69 years × 1024 machines × 4096 IDs/ms per machine.

区别于旧式 ID 生成:

  • Singleton 模式,业务侧直接调 SnowflakeID() 拿下一个 int64 ID.
  • 时钟回拨持锁忙等,不返错.
  • API 极简:InitSnowflake + SnowflakeID,不暴露 mu / sequence / lastTS.

并发模型:

  • InitSnowflake 用 atomic.Pointer CAS 保证 "只 init 一次" + "成功后立刻可见".
  • SnowflakeID() auto-init 路径在 CAS 失败时回退到 Load(),避免 nil deref.
  • next() 持单 mu 串行:临界区短(同 ms 仅几次算术,跨 ms 持锁等下 ms 最坏 1ms).

Reference: https://github.com/twitter-archive/snowflake (Twitter, 2010)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL