hgmIdGen

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: Unlicense Imports: 6 Imported by: 0

README

hgmIdGen

一个零依赖的 Go id 生成库.通过 时间 + 进程内递增计数 + 强随机 组合,生成大概率递增、低碰撞、只含安全字符的 id.

go get github.com/hgmGoLib/hgmIdGen
import "github.com/hgmGoLib/hgmIdGen"

能干啥

提供 3 种输出,按用途分别选用:

场景 调用 结果例子 长度
一般数据库主键 (userId/orderId/postId) hgmIdGen.NewId() 17fatw9hnw1y8ge6emw3et3fmtu9d 固定 29 字符
高安全 token (sessionId/accessToken) hgmIdGen.NewSecureId() 17fatweptd1swfgg11ekgtx5j459wnf112v7jp81wn 固定 42 字符
二进制 id (省内存/自定义存储) hgmIdGen.NewIdBinary(dst) 固定 18 字节

两种字符串方案都保证:结果只含不易混淆的安全字符、同进程连续调用大概率递增、时间+递增+随机组合避免简单碰撞.

怎么干

生成 id
id := hgmIdGen.NewId()             // 数据库主键
token := hgmIdGen.NewSecureId()    // 高安全 token

var buf []byte
buf = hgmIdGen.NewIdBinary(buf)    // 18 字节二进制,dst 传 nil 则新分配
二进制与字符串互转

NewIdBinaryNewId 是同一套方案,只差 base32 编码,可无损互转:

str, err := hgmIdGen.IdBinaryToId(bin)   // 18 字节 -> 29 字符
bin, err := hgmIdGen.IdToIdBinary(str)   // 29 字符 -> 18 字节
校验外部传入的字符串
hgmIdGen.IsValidId(s)        // 是否是合法的 NewId() 格式
hgmIdGen.IsValidSecureId(s)  // 是否是合法的 NewSecureId() 格式
从 id 反查生成时间
hgmIdGen.ParseTimeFromId(id)         // NewId() 结果 -> 毫秒时间
hgmIdGen.ParseTimeFromSecureId(id)   // NewSecureId() 结果 -> 毫秒时间
解析失败统一返回 time.Time{}.
按时间范围扫描的下界

需要 where id >= ? 这种按时间范围扫描时,用对应的最小值构造:

hgmIdGen.MinIdAtTime(t)         // 某毫秒时刻的最小 NewId()
hgmIdGen.MinSecureIdAtTime(t)   // 某毫秒时刻的最小 NewSecureId()

选型注意

  • NewId() 适合数据库主键,没人故意 ddos 的情况下极难碰撞.
  • NewSecureId() 随机段更长,即使有人故意撞库也很难碰撞,用于 sessionId / accessToken.

实现细节

  • NewId() (18 字节): 6 字节毫秒时间 (约可表示 8925 年) + 1~4 字节变长递增计数 (前 2 位表示字节数,承载 6~30 bit,最大 2^30-1,时间变化即归零) + 8~11 字节强随机,最后整体 base32 编码为 29 字符.
  • NewSecureId() (26 字节): 结构同上,但随机段扩到 16~19 字节,抗碰撞更强,base32 编码为 42 字符.
  • base32 字符表: 123456789abcdefghjkmnpqrstuvwxyz,去掉易混淆字符,且按 ascii 递增,保证编码结果可直接字符串排序.

更细的逐字段说明可直接阅读对应源码文件 (Id_*.go / SecureId_*.go / IdBinary_*.go).

License

Unlicense (public domain).

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IdBinaryToId

func IdBinaryToId(bin []byte) (string, error)

把18字节二进制id转换为29字符的base32字符串id,和NewId()的输出格式一致.

func IdToIdBinary

func IdToIdBinary(id string) ([]byte, error)

把29字符的base32字符串id转换为18字节二进制id.

func IsValidId

func IsValidId(id string) bool

IsValidId 判断一个字符串是否为合法的普通 id(base32编码,长度29)

func IsValidSecureId

func IsValidSecureId(id string) bool

IsValidSecureId 判断一个字符串是否为合法的高安全 id(base32编码,长度42)

func MinIdAtTime

func MinIdAtTime(t time.Time) string

生成指定毫秒时刻对应的最小普通数据库 id,适合做数据库时间范围扫描下界。 最小 id 即: 6 字节时间 + 后续递增和随机段全 0, 再 base32 编码.

func MinSecureIdAtTime

func MinSecureIdAtTime(t time.Time) string

生成指定毫秒时刻对应的最小高安全 id,适合做数据库时间范围扫描下界。 最小 id 即: 6 字节时间 + 后续递增和随机段全 0, 再 base32 编码.

func NewId

func NewId() string

输出结果例子 17fatw9hnw1y8ge6emw3et3fmtu9d 字符串固定长度 29 普通 id ========== * 适合一般数据库对象的id生成.在没有人故意ddos 的情况下很难碰撞上. * 固定 18个字节二进制. * 6个字节 时间到毫秒. ( 大约 8925 年) * 1-4个字节 递增变长编码 当前进程挂锁顺序增加id (时间变了之后,从0 开始递增) (2位表示后面有几个字节,6-30位表示后面的id 最大 2^30-1 = 1073741823) * 8-11个字节 随机二进制数据.(来自强随机api) * 然后base32 编码 使用不易混淆的 字符,使用按ascii码递增排列的字符串

func NewIdBinary

func NewIdBinary(dst []byte) []byte

生成18字节固定长度的二进制id,方案和NewId()完全一致,只是跳过了base32编码步骤. 传入dst用于复用内存分配,结果append到dst后面返回.

func NewSecureId

func NewSecureId() string

输出结果例子 17fatweptd1swfgg11ekgtx5j459wnf112v7jp81wn 字符串固定长度 42 高安全 id ========== * 适合高安全性要求的id生成. 比如 sessionId 和 acceessToken 有人故意ddos碰撞也很难碰撞上. * 固定 26个字节二进制. * 6个字节 时间到毫秒. ( 大约 8925 年) * 1-4个字节 递增变长编码 当前进程挂锁顺序增加id (时间变了之后,从0 开始递增) (2位表示后面有几个字节,6-30位表示后面的id 最大 2^30-1 = 1073741823) * 16-19个字节 随机二进制数据.(来自强随机api) * 然后base32 编码 使用不易混淆的 字符,使用按ascii码递增排列的字符串

func ParseTimeFromId

func ParseTimeFromId(id string) time.Time

解析普通数据库 id 里的毫秒时间,失败时返回零值时间。

func ParseTimeFromSecureId

func ParseTimeFromSecureId(id string) time.Time

解析高安全 id 里的毫秒时间,失败时返回零值时间。

Types

This section is empty.

Jump to

Keyboard shortcuts

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