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原生库的中bytes.Buffer用法
Apr 25 Golang
彻底理解golang中什么是nil
Apr 29 Golang
浅谈golang 中time.After释放的问题
May 05 Golang
Golang 编译成DLL文件的操作
May 06 Golang
使用golang编写一个并发工作队列
May 08 Golang
Golang原生rpc(rpc服务端源码解读)
Apr 07 Golang
Golang数据类型和相互转换
Apr 12 Golang
Go语言grpc和protobuf
Apr 13 Golang
实现GO语言对数组切片去重
Apr 20 Golang
Golang 结构体数据集合
Apr 22 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 pcntl_fork和pcntl_fork 的用法
2009/04/13 PHP
PHP读取大文件的类SplFileObject使用介绍
2014/04/09 PHP
PHP的Socket网络编程入门指引
2015/08/11 PHP
php实现的http请求封装示例
2016/11/08 PHP
基于jQuery的动态表格插件
2011/03/28 Javascript
javascript 文本框水印/占位符(watermark/placeholder)实现方法
2012/01/15 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
浅析hasOwnProperty方法的应用
2013/11/20 Javascript
用js来刷新当前页面保留参数的具体实现
2013/12/23 Javascript
js实现按一下删除键删除整个单词附demo
2014/09/05 Javascript
Winform客户端向web地址传参接收参数的方法
2016/05/17 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的方法
2016/11/29 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
2016/12/30 Javascript
Angular.js中数组操作的方法教程
2017/07/31 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
JavaScript学习笔记之图片库案例分析
2019/01/08 Javascript
微信小程序实现用table显示数据库反馈的多条数据功能示例
2019/05/07 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
vuejs实现下拉框菜单选择
2020/10/23 Javascript
Python实现的堆排序算法示例
2018/04/29 Python
Python 中Django验证码功能的实现代码
2019/06/20 Python
tensor和numpy的互相转换的实现示例
2019/08/02 Python
Python 过滤错误log并导出的实例
2019/12/26 Python
PyTorch和Keras计算模型参数的例子
2020/01/02 Python
珍珠奶茶店创业计划书
2014/01/11 职场文书
集体婚礼证婚词
2014/01/13 职场文书
医务工作者先进事迹材料
2014/01/26 职场文书
安全目标责任书
2014/07/22 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
“5.12”护士节主持词
2015/07/04 职场文书
MySQL Innodb关键特性之插入缓冲(insert buffer)
2021/04/08 MySQL
Python中使用ipython的详细教程
2021/06/22 Python
Java使用JMeter进行高并发测试
2021/11/23 Java/Android
《勇者辞职不干了》ED主题曲无字幕动画MV公开
2022/04/13 日漫