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 interface{}==nil 的几种坑及原理分析
Apr 24 Golang
golang中切片copy复制和等号复制的区别介绍
Apr 27 Golang
golang http使用踩过的坑与填坑指南
Apr 27 Golang
Golang中interface{}转为数组的操作
Apr 30 Golang
解决golang结构体tag编译错误的问题
May 02 Golang
Golang: 内建容器的用法
May 05 Golang
golang中的struct操作
Nov 11 Golang
Go 中的空白标识符下划线
Mar 25 Golang
Golang map映射的用法
Apr 22 Golang
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 Golang
Golang 并发编程 SingleFlight模式
Apr 26 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 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
js和php邮箱地址验证的实现方法
2014/01/09 PHP
php使用gettimeofday函数返回当前时间并存放在关联数组里
2015/03/19 PHP
PHP获取毫秒级时间戳的方法
2015/04/15 PHP
PHP检测用户语言的方法
2015/06/15 PHP
php简单检测404页面的方法示例
2019/08/23 PHP
跨浏览器的设置innerHTML方法
2006/09/18 Javascript
推荐20家国外的脚本下载网站
2011/04/28 Javascript
jquery实现div阴影效果示例代码
2013/09/16 Javascript
jquery查找父元素、子元素(个人经验总结)
2014/04/09 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
2015/07/29 Javascript
直接拿来用的页面跳转进度条JS实现
2016/01/06 Javascript
Vue实现自带的过滤器实例
2017/03/09 Javascript
简单谈谈React中的路由系统
2017/07/25 Javascript
[03:20]2015国际邀请赛全明星表演赛
2015/08/08 DOTA
[01:01:18]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#2COL VS LGD
2016/03/03 DOTA
[01:05:56]2018DOTA2亚洲邀请赛3月29日 小组赛A组 Newbee VS VG
2018/03/30 DOTA
粗略分析Python中的内存泄漏
2015/04/23 Python
python3操作微信itchat实现发送图片
2018/02/24 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
2019/12/10 Python
python 等差数列末项计算方式
2020/05/03 Python
python如何导入依赖包
2020/07/13 Python
python的数学算法函数及公式用法
2020/11/18 Python
使用CSS3实现字体颜色渐变的实现
2020/08/10 HTML / CSS
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
日本小田急百货官网:Odakyu
2018/07/19 全球购物
英文版网络工程师求职信
2013/10/28 职场文书
大学生怎样进行自我评价
2013/12/07 职场文书
新郎新娘婚礼答谢词
2014/01/11 职场文书
个人简历自我评价范文
2014/02/04 职场文书
销售岗位职责范本
2014/06/12 职场文书
2014年学校国庆主题活动方案
2014/09/16 职场文书
国际贸易本科毕业生求职信
2014/09/26 职场文书
幼儿教师师德师风自我剖析材料
2014/09/29 职场文书
敲诈同学钱财检讨书范文
2014/11/18 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL