前言
我正在學習酷酷的 Golang,可點此查看帖子Golang學習筆記彙總。
0 uuid 基礎
UUID(Universally Unique IDentifier)是一個128位數字的唯一標識。
格式
UUID使用16進製表示,共有36個字符(32個字母數字+4個連接符"-"),格式爲8-4-4-4-12,如:
6d25a684-9558-11e9-aa94-efccd7a0659b
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M中使用4位來表示UUID的版本,N中使用1-3位表示不同的variant。如上面所示:M =1, N = a表示此UUID爲version-1,variant-1的UUID(Time-based ECE/RFC 4122 UUID)。
但是爲什麼最開始說它是一個128位的唯一標識呢?這裏明明字母位數是(8+4+4+4+12)*8=256位。
因爲上面的字母是用的16進制,一個16進制只代表4個bit,所以應該是(8+4+4+4+12)*4=128位。
5種版本
UUID現有5種版本,是根據不同的使用場景劃分的,而不是根據精度,所以Version5並不會比Version1精度高,在精度上,大家都能保證唯一性,重複的概率近乎於0。
- Version 1, based on timestamp and MAC address (RFC-4122)
- Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
- Version 3, based on MD5 hashing of a named value (RFC-4122)
- Version 4, based on random numbers (RFC-4122)
- Version 5, based on SHA-1 hashing of a named value (RFC-4122)
如何使用5種版本
V4 是使用最爲廣泛的。
如果只是需要生成一個唯一ID,你可以使用V1或V4。
- V1基於時間戳和Mac地址,這些ID有一定的規律(你給出一個,是有可能被猜出來下一個是多少的),而且會暴露你的Mac地址。
- V4是完全隨機(僞)的。
如果對於相同的參數需要輸出相同的UUID,你可以使用V3或V5。
- V3基於MD5 hash算法,如果需要考慮與其它系統的兼容性的話,就用它,因爲它出來得早,大概率大家都是用它的。
- V5基於SHA-1 hash算法,這個是首選。
1 庫的介紹
Package uuid provides a pure Go implementation of Universally Unique Identifiers
(UUID) variant as defined in RFC-4122. This package supports both the creation
and parsing of UUIDs in different formats.
UUID 有 5 種版本,這個庫都能完美支持。
直接安裝做個測試。
go get github.com/gofrs/uuid
2 官方示例
package main
import (
"log"
"github.com/gofrs/uuid"
)
// Create a Version 4 UUID, panicking on error.
// Use this form to initialize package-level variables.
var u1 = uuid.Must(uuid.NewV4())
func main() {
// Create a Version 4 UUID.
u2, err := uuid.NewV4()
if err != nil {
log.Fatalf("failed to generate UUID: %v", err)
}
log.Printf("generated Version 4 UUID %v", u2)
// Parse a UUID from a string.
s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
u3, err := uuid.FromString(s)
if err != nil {
log.Fatalf("failed to parse UUID %q: %v", s, err)
}
log.Printf("successfully parsed UUID %v", u3)
}
測試結果
2020/02/23 12:12:46 generated Version 4 UUID 34b0e422-c7be-404a-8861-a543af8393c8
2020/02/23 12:12:46 successfully parsed UUID 6ba7b810-9dad-11d1-80b4-00c04fd430c8
函數分析
生成 uuid
// NewV4 returns a randomly generated UUID.
func NewV4() (UUID, error) {
return DefaultGenerator.NewV4()
}
Generator 提供了5種版本的uuid生成方式。
// Generator provides an interface for generating UUIDs.
type Generator interface {
NewV1() (UUID, error)
NewV2(domain byte) (UUID, error)
NewV3(ns UUID, name string) UUID
NewV4() (UUID, error)
NewV5(ns UUID, name string) UUID
}
生成 uuid 的封裝
Must 是對生成函數的封裝,新增了 error 處理。
// Must is a helper that wraps a call to a function returning (UUID, error)
// and panics if the error is non-nil. It is intended for use in variable
// initializations such as
// var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000"))
func Must(u UUID, err error) UUID {
if err != nil {
panic(err)
}
return u
}
解析 uuid
// FromString returns a UUID parsed from the input string.
// Input is expected in a form accepted by UnmarshalText.
func FromString(input string) (UUID, error) {
u := UUID{}
err := u.UnmarshalText([]byte(input))
return u, err
}
3 小結
uuid 包支持5種uuid的生成及解析,最廣泛使用的就是生成一個V4版本的 uuid:
u1 = uuid.Must(uuid.NewV4())