GoLang中生成UUID唯一标识的实现


Posted in Golang onMay 08, 2021

1、什么是UUID

UUID简介

通用唯一识别码(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为自由软件基金会组织在分散式计算环境领域的一部份。

UUID的目的,是让分散式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。

如此一来,每个人都可以创建不与其它人冲突的UUID。

在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的UUID,是微软公司的全局唯一标识符(GUID),而其他重要的应用,则有Linux ext2/ext3文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等等。

2、Go中现有的UUID第三方生成办法

目前,golang中的uuid还没有纳入标准库,我们使用github上的开源库:

go get -u github.com/satori/go.uuid

使用:

package main 
import (
    "fmt"
    "github.com/satori/go.uuid"
)
 
func main() {
   id := uuid.NewV4()
   ids := id.String()
}

3、自定义的 UUIDGenerator实现

功能:

UUIDGenerator 可以生成全局唯一的字符串形式的ID,ID由两部分构成,一部分是用户指定的前缀,另一部分是数字,数字的最大值为 4294967295;

UUIDGenerator 可以生成全局唯一的无符号整形数字,数字范围 0- 4294967295

代码

package utils 
import "fmt"
 
const (
    MAXUINT32 = 4294967295
    DEFAULT_UUID_CNT_CACHE = 512
)
 
type UUIDGenerator struct {
    Prefix       string
    idGen        uint32
    internalChan chan uint32
}
 
func NewUUIDGenerator(prefix string) *UUIDGenerator {
    gen := &UUIDGenerator{
        Prefix:       prefix,
        idGen:        0,
        internalChan: make(chan uint32, DEFAULT_UUID_CNT_CACHE),
    }
    gen.startGen()
    return gen
}
 
//开启 goroutine, 把生成的数字形式的UUID放入缓冲管道
func (this *UUIDGenerator) startGen() {
    go func() {
        for {
            if this.idGen == MAXUINT32 {
                this.idGen = 1
            } else {
                this.idGen += 1
            }
            this.internalChan <- this.idGen
        }
    }()
}
 
//获取带前缀的字符串形式的UUID
func (this *UUIDGenerator) Get() string {
    idgen := <-this.internalChan
    return fmt.Sprintf("%s%d", this.Prefix, idgen)
}
 
//获取uint32形式的UUID
func (this *UUIDGenerator) GetUint32() uint32 {
    return <-this.internalChan
}

测试用例:

package utils 
import (
    "testing"
    "fmt"
)
 
func TestUUIDGenerator(t *testing.T) {
    //新建UUIDGennerator
    UUIDFactory := NewUUIDGenerator("idtest")
 
    //获取UUID
    for i:= 0; i < 50; i++{
        fmt.Println(UUIDFactory.Get())
    }
 
    //获取uint32 形式的UUID
    for i := 0; i < 50; i++{
        fmt.Println(UUIDFactory.GetUint32())
    }
}

结果

idtest1

idtest2

idtest3

idtest4

idtest5

6

7

8

9

10

PASS

补充:golang 的 UUID 使用

安装

go get github.com/satori/go.uuid

使用

几种 UUID 的产生方式:

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 (RFC 4122)
Version 4, based on random numbers (RFC 4122)
Version 5, based on SHA-1 hashing (RFC 4122)

示例代码:

package main
import (
    "fmt"
    "github.com/satori/go.uuid"
)
func main() {
    // Creating UUID Version 4
    // panic on error
    u1 := uuid.Must(uuid.NewV4())
    fmt.Printf("UUIDv4: %s\n", u1)
    // or error handling
    u2, err := uuid.NewV4()
    if err != nil {
        fmt.Printf("Something went wrong: %s", err)
        return
    }
    fmt.Printf("UUIDv4: %s\n", u2)
    // Parsing UUID from string input
    u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
    if err != nil {
        fmt.Printf("Something went wrong: %s", err)
    }
    fmt.Printf("Successfully parsed: %s", u2)
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。如有错误或未考虑完全的地方,望不吝赐教。

Golang 相关文章推荐
golang中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
goland 清除所有的默认设置操作
Apr 28 Golang
解决golang在import自己的包报错的问题
Apr 29 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
Go标准容器之Ring的使用说明
May 05 Golang
完美解决golang go get私有仓库的问题
May 05 Golang
Go 自定义package包设置与导入操作
May 06 Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 Golang
golang 语言中错误处理机制
Aug 30 Golang
Golang获取List列表元素的四种方式
Apr 20 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
在ubuntu下安装go开发环境的全过程
Aug 05 Golang
聊聊golang中多个defer的执行顺序
May 08 #Golang
Golang全局变量加锁的问题解决
golang 实现并发求和
May 08 #Golang
golang中的并发和并行
May 08 #Golang
关于golang高并发的实现与注意事项说明
May 08 #Golang
基于Golang 高并发问题的解决方案
May 08 #Golang
使用golang编写一个并发工作队列
May 08 #Golang
You might like
PHP开发文件系统实例讲解
2006/10/09 PHP
自动跳转中英文页面
2006/10/09 PHP
PHP Global定义全局变量使用说明
2013/08/15 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
Javascript 颜色渐变效果的实现代码
2013/10/01 Javascript
js表格排序实例分析(支持int,float,date,string四种数据类型)
2015/05/06 Javascript
AngularJS入门心得之directive和controller通信过程
2016/01/25 Javascript
angularjs 表单密码验证自定义指令实现代码
2016/10/27 Javascript
Form表单按回车自动提交表单的实现方法
2016/11/18 Javascript
canvas 画布在主流浏览器中的尺寸限制详细介绍
2016/12/15 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
vue中父子组件注意事项,传值及slot应用技巧
2018/05/09 Javascript
JS实现获取毫秒值及转换成年月日时分秒的方法
2018/08/15 Javascript
javascript中函数的写法实例代码详解
2018/10/28 Javascript
node(koa2) web应用模块介绍详解
2019/03/29 Javascript
VUE写一个简单的表格实例
2019/08/06 Javascript
详解vue beforeRouteEnter 异步获取数据给实例问题
2019/08/09 Javascript
JS替换字符串中指定位置的字符(多种方法)
2020/05/28 Javascript
[01:04]DOTA2:伟大的Roshan雕塑震撼来临
2015/01/30 DOTA
python中 logging的使用详解
2017/10/25 Python
GitHub 热门:Python 算法大全,Star 超过 2 万
2019/04/29 Python
flask框架自定义过滤器示例【markdown文件读取和展示功能】
2019/11/08 Python
Python脚本去除文件的只读性操作
2020/03/05 Python
python 使用raw socket进行TCP SYN扫描实例
2020/05/05 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
2020/05/25 Python
浅谈Python 参数与变量
2020/06/20 Python
详解CSS3 filter:drop-shadow滤镜与box-shadow区别与应用
2020/08/24 HTML / CSS
html5定制表单_动力节点Java学院整理
2017/07/11 HTML / CSS
瑞典手机壳品牌:Richmond & Finch
2018/04/28 全球购物
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
The North Face北面法国官网:美国著名户外品牌
2019/11/01 全球购物
物流专业大学生职业生涯规划书范文
2014/01/15 职场文书
小学生元旦感言
2014/02/26 职场文书
献爱心标语
2014/06/21 职场文书
2015年元宵节活动总结
2015/02/06 职场文书
工程移交协议书
2016/03/24 职场文书