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中ResponseWriter的一个坑
Apr 27 Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
Go语言 go程释放操作(退出/销毁)
Apr 30 Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
golang内置函数len的小技巧
Jul 25 Golang
Go Plugins插件的实现方式
Aug 07 Golang
Golang 并发编程 SingleFlight模式
Apr 26 Golang
Golang解析JSON对象
Apr 30 Golang
Golang入门之计时器
May 04 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
一个用于MySQL的PHP XML类
2006/10/09 PHP
php中判断数组是一维,二维,还是多维的解决方法
2013/05/04 PHP
一个显示效果非常不错的PHP错误、异常处理类
2014/03/21 PHP
浅谈php的TS和NTS的区别
2019/03/13 PHP
非常不错的功能强大代码简单的管理菜单美化版
2008/07/09 Javascript
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
JavaScript Event学习第七章 事件属性
2010/02/07 Javascript
javascript学习笔记(十三) js闭包介绍(转)
2012/06/20 Javascript
jquery 倒计时效果实现秒杀思路
2013/09/11 Javascript
iframe子父页面调用js函数示例
2013/11/07 Javascript
使用ajaxfileupload.js实现ajax上传文件php版
2014/06/26 Javascript
js点击button按钮跳转到另一个新页面
2014/10/10 Javascript
跟我学习javascript的循环
2015/11/18 Javascript
js提示框替代系统alert,自动关闭alert对话框的实现方法
2016/11/07 Javascript
Javascript中的 “&amp;” 和 “|” 详解
2017/02/02 Javascript
Vue filter介绍及其使用详解
2017/10/21 Javascript
解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题
2018/05/17 Javascript
Vue数字输入框组件示例代码详解
2020/01/15 Javascript
javascript canvas检测小球碰撞
2020/04/17 Javascript
简介JavaScript错误处理机制
2020/08/04 Javascript
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
[16:56]教你分分钟做大人:司夜刺客
2014/10/30 DOTA
[01:06:30]DOTA2-DPC中国联赛定级赛 Phoenix vs DLG BO3第二场 1月9日
2021/03/11 DOTA
python进阶教程之循环相关函数range、enumerate、zip
2014/08/30 Python
Python中使用urllib2模块编写爬虫的简单上手示例
2016/01/20 Python
Python使用gensim计算文档相似性
2016/04/10 Python
Python中的is和==比较两个对象的两种方法
2017/09/06 Python
通过Py2exe将自己的python程序打包成.exe/.app的方法
2018/05/26 Python
使用python将请求的requests headers参数格式化方法
2019/01/02 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
linux查找当前python解释器的位置方法
2019/02/20 Python
Python递归函数实例讲解
2019/02/27 Python
使用JS+CSS3技术:让你的名字动起来
2013/04/27 HTML / CSS
2014年文明创建工作总结
2014/11/25 职场文书
班主任远程培训研修日志
2015/11/13 职场文书
Python数据处理的三个实用技巧分享
2022/04/01 Python