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 如何通过反射创建新对象
Apr 28 Golang
彻底理解golang中什么是nil
Apr 29 Golang
golang import自定义包方式
Apr 29 Golang
Go使用协程交替打印字符
Apr 29 Golang
解决Go gorm踩过的坑
Apr 30 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
Golang 编译成DLL文件的操作
May 06 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
手把手教你导入Go语言第三方库
Aug 04 Golang
Golang 结构体数据集合
Apr 22 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 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和Java的des加密解密代码分享
2014/06/26 PHP
php数组函数array_walk用法示例
2016/05/26 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
2016/07/15 PHP
PHP生成word文档的三种实现方式
2016/11/14 PHP
详解Laravel5.6 Passport实现Api接口认证
2018/07/27 PHP
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
关于firefox的ElementTraversal 接口 使用说明
2010/11/11 Javascript
javascript学习(一)构建自己的JS库
2013/01/02 Javascript
用JavaScript实现类似于ListBox功能示例代码
2014/03/09 Javascript
jQuery中:contains选择器用法实例
2014/12/30 Javascript
Js与Jq 获取页面元素值的方法和差异对比
2015/04/30 Javascript
jQuery的实例及必知重要的jQuery选择器详解
2016/05/20 Javascript
AngularJS入门教程之数据绑定用法示例
2016/11/01 Javascript
jQuery联动日历的实例解析
2016/12/02 Javascript
详解为Angular.js内置$http服务添加拦截器的方法
2016/12/20 Javascript
js字符串与Unicode编码互相转换
2017/05/17 Javascript
node+vue实现用户注册和头像上传的实例代码
2017/07/20 Javascript
AngularJS 表单验证手机号的实例(非必填)
2017/11/12 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
vue实现的下拉框功能示例
2019/01/29 Javascript
如何通过shell脚本自动生成vue文件详解
2019/09/10 Javascript
python常见的格式化输出小结
2016/12/15 Python
Python连接phoenix的方法示例
2017/09/29 Python
详解python中Numpy的属性与创建矩阵
2018/09/10 Python
python代码实现逻辑回归logistic原理
2019/08/07 Python
python中元组的用法整理
2020/06/15 Python
浅谈pandas dataframe对除数是零的处理
2020/07/20 Python
python利用platform模块获取系统信息
2020/10/09 Python
python 获取域名到期时间的方法步骤
2021/02/10 Python
css3 2D图片转动样式可以扩充到Js当中
2014/04/29 HTML / CSS
销售冠军获奖感言
2014/02/03 职场文书
2014年调度员工作总结
2014/11/19 职场文书
中学教师读书笔记
2015/07/01 职场文书
小学生教师节广播稿
2015/08/19 职场文书
导游词之吉林花园山
2019/10/17 职场文书
Jupyter notebook 输出部分显示不全的解决方案
2021/04/24 Python