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 相关文章推荐
go语言求任意类型切片的长度操作
Apr 26 Golang
Go语言中break label与goto label的区别
Apr 28 Golang
golang 实现Location跳转方式
May 02 Golang
go设置多个GOPATH的方式
May 05 Golang
Golang: 内建容器的用法
May 05 Golang
go类型转换及与C的类型转换方式
May 05 Golang
解决golang 关于全局变量的坑
May 06 Golang
go 实现简易端口扫描的示例
May 22 Golang
Go timer如何调度
Jun 09 Golang
golang用type-switch判断interface的实际存储类型
Apr 14 Golang
Go web入门Go pongo2模板引擎
May 20 Golang
详解Go语言中配置文件使用与日志配置
Jun 01 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
如何给phpcms v9增加类似于phpcms 2008中的关键词表
2013/07/01 PHP
正确的PHP匹配UTF-8中文的正则表达式
2015/05/13 PHP
PHP基于Closure类创建匿名函数的方法详解
2017/08/17 PHP
Domino中运用jQuery读取视图内容的方法
2009/10/21 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
查询json的数据结构的8种方式简介
2014/03/10 Javascript
跟我学习javascript的最新标准ES6
2015/11/20 Javascript
深入理解Angular4订阅(Subscribe)与取消
2017/11/22 Javascript
利用Javascript获取选择文本所在的句子详解
2017/12/03 Javascript
webpack4打包vue前端多页面项目
2018/09/17 Javascript
python将xml xsl文件生成html文件存储示例讲解
2013/12/03 Python
python中的字典详细介绍
2014/09/18 Python
十个Python程序员易犯的错误
2015/12/15 Python
python使用matplotlib画饼状图
2018/09/25 Python
简单了解python单例模式的几种写法
2019/07/01 Python
Python TKinter如何自动关闭主窗口
2020/02/26 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
用Python生成HTML表格的方法示例
2020/03/06 Python
python 解决mysql where in 对列表(list,,array)问题
2020/06/06 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
python函数超时自动退出的实操方法
2020/12/28 Python
Pyecharts 中Geo函数常用参数的用法说明
2021/02/01 Python
基于IE10/HTML5 开发
2013/04/22 HTML / CSS
世界上最悠久的自行车制造商:Ribble Cycles
2017/03/18 全球购物
德国玩具商店:Planet Happy DE
2021/01/16 全球购物
50道外企软件测试面试题
2014/08/18 面试题
小学教师岗位职责
2013/11/25 职场文书
七年级历史教学反思
2014/02/05 职场文书
诚信的演讲稿范文
2014/05/12 职场文书
寻找最美家庭活动方案
2014/08/20 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
2015年民主评议党员工作总结
2015/05/19 职场文书
2015年清剿火患专项行动工作总结
2015/07/27 职场文书
八年级作文之我的母亲
2019/12/10 职场文书
Centos系统通过Docker安装并搭建MongoDB数据库
2022/04/12 MongoDB
java开发双人五子棋游戏
2022/05/06 Java/Android