github.com/google/uuid

uuid是Universally Unique Identifier的缩写,即通用唯一识别码

uuid的目的是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 uuid。

uuid是谷歌开发的生成16字节UUID的模块,实现了RFC4122;对UUID的v1,v2,v3,v4,v5等各个版本都有实现。一般来说,如果只是要生成唯一序列号的话,通常用v4版本,New()和NewRandom()都可以生成v4, New是对NewRandom的封装把error处理成panics了,但是理论上几乎是不会有发生panics的可能的。

func New() UUID
func NewRandom() (UUID, error)
package main

import (
	"fmt"
	"github.com/google/uuid"
)

func main() {
	for i:=0; i<2; i++ {
		id := uuid.New()
		fmt.Printf("%T,%v\n",id,id)
		fmt.Printf("%v,%v,%v\n",id.String(),id.Version(),id.Version().String())
	}

	fmt.Println("-------------------------------")

	for i:=0; i<2; i++ {
		id2,err := uuid.NewRandom()
		if err != nil {
			fmt.Println(err)
		}
		fmt.Printf("%T,%v\n",id2,id2)
		fmt.Printf("%v,%v,%v\n",id2.String(),id2.Version(),id2.Version().String())
	}
}

在这里插入图片描述
官方文档上说New方法可能会有panics,但从源码来看基本上没有报错的可能。会不会报错取决于"crypto/rand"的Reader能不能读满到16个随机字节,而Reader又是从Linux操作系统的getrandom(2) 读取若没有则从 /dev/urandom 读取,getrandom(2)的文档说256个字节以内都不会被信号中断,而/dev/urandom的文档也没有说会有报错的可能。所以理论上是没有报错的可能的。

uuid是谷歌开发的生成16字节UUID的模块,实现了RFC4122;对UUID的v1,v2,v3,v4,v5等各个版本都有实现。使用方法示例如下:

package main

import (
	"fmt"
	"github.com/google/uuid"
)

// v1,v4都是每次生成一个唯一的ID.
// v1同一时刻的输出非常相似,v1末尾nodeID部分用的都是mac地址,前面time的mid,high以及clock序列都是一样的,只有time-low部分不同。
func testv1() {
	id,err := uuid.NewUUID()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("testv1: %v,%v\n",id,id.Version().String())
}

// v4加入了随机数,对各个部分都进行了随机处理,同一时刻的输出差别很大。
func testv4() {
	id := uuid.New()
	fmt.Printf("testv4: %v,%v\n",id,id.Version().String())
}

// v2 NewDCEGroup()根据os.Getgid取到的用户组ID来生成uuid,同一时刻的输出是相同的。
func testv2G() {
	id,err := uuid.NewDCEGroup()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("testv2G: %v,%v\n",id,id.Version().String())
}

// v2 NewDCEPerson()根据os.Getuid取到的用户ID来生成uuid,同一时刻的输出也是相同的。
func testv2P() {
	id,err := uuid.NewDCEPerson()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("testv2P: %v,%v\n",id,id.Version().String())
}

// v3 NewMD5(space UUID, data []byte)是根据参数传入的UUID结构体和[]byte再重新转换一次。只要传入参数相同则任意时刻的输出也相同。
func testv3() {
	id0,err := uuid.NewDCEPerson()
	if err != nil {
		fmt.Println(err)
		return
	}
	id := uuid.NewMD5(id0,[]byte("fssds32"))
	fmt.Printf("testv3: %v,%v\n",id,id.Version().String())
}

// v5 NewSHA1(space UUID, data []byte)是根据参数传入的UUID结构体和[]byte再重新转换一次。只要传入参数相同则任意时刻的输出也相同。
func testv5() {
	id0,err := uuid.NewDCEPerson()
	if err != nil {
		fmt.Println(err)
		return
	}
	id := uuid.NewSHA1(id0,[]byte("fssds32"))
	fmt.Printf("testv5: %v,%v\n",id,id.Version().String())
}

func main() {
	for i:=0; i<2; i++ {
		testv1()
	}

	fmt.Println("--------------------")

	for i:=0; i<2; i++ {
		testv4()
	}

	fmt.Println("--------------------")

	for i:=0; i<2; i++ {
		testv2G()
	}

	fmt.Println("--------------------")

	for i:=0; i<2; i++ {
		testv2P()
	}

	fmt.Println("--------------------")

	for i:=0; i<2; i++ {
		testv3()
	}

	fmt.Println("--------------------")

	for i:=0; i<2; i++ {
		testv5()
	}

	fmt.Println("--------------------")
}

在这里插入图片描述

结论:

v1,v4都是每次生成一个唯一的ID,而v1同一时刻的输出非常相似,v1末尾nodeID部分用的都是mac地址,前面time的mid,high以及clock序列都是一样的,只有time-low部分不同。
v4加入了随机数,对各个部分都进行了随机处理,同一时刻的输出差别很大。
  
v2 NewDCEGroup()根据os.Getgid取到的用户组ID来生成uuid,同一时刻的输出是相同的。

v2 NewDCEPerson()根据os.Getuid取到的用户ID来生成uuid,同一时刻的输出也是相同的。

v3 NewMD5(space UUID, data []byte)是根据参数传入的UUID结构体和[]byte再重新转换一次。只要传入参数相同则任意时刻的输出也相同。

v5 NewSHA1(space UUID, data []byte)是根据参数传入的UUID结构体和[]byte再重新转换一次。只要传入参数相同则任意时刻的输出也相同。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值