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 interface判断为空nil的实现代码
Apr 24 Golang
go语言求任意类型切片的长度操作
Apr 26 Golang
go结构体嵌套的切片数组操作
Apr 28 Golang
Golang全局变量加锁的问题解决
May 08 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
Go语言实现一个简单的并发聊天室的项目实战
Mar 18 Golang
golang操作rocketmq的示例代码
Apr 06 Golang
Golang 1.18 多模块Multi-Module工作区模式的新特性
Apr 11 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Go Grpc Gateway兼容HTTP协议文档自动生成网关
Jun 16 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
玩转图像函数库―常见图形操作
2006/09/03 PHP
PHP 配置open_basedir 让各虚拟站点独立运行
2009/11/12 PHP
9个PHP开发常用功能函数小结
2011/07/15 PHP
解析thinkphp中的导入文件标签
2013/06/20 PHP
web server使用php生成web页面的三种方法总结
2013/10/28 PHP
PHP实现WebService的简单示例和实现步骤
2015/03/27 PHP
php微信公众账号开发之前五个坑(一)
2016/09/18 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
COM中获取JavaScript数组大小的代码
2009/11/22 Javascript
javascript window.opener的用法分析
2010/04/07 Javascript
js 删除数组的几种方法小结
2014/02/21 Javascript
JavaScript字符串对象的concat方法实例(用于连接两个或多个字符串)
2014/10/16 Javascript
fastclick插件导致日期(input[type=&quot;date&quot;])控件无法被触发该如何解决
2015/11/09 Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
2016/10/28 Javascript
Angular实现购物车计算示例代码
2017/02/21 Javascript
javascript Function函数理解与实战
2017/12/01 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
Bootstrap 按钮样式与使用代码详解
2018/12/09 Javascript
JS Math对象与Math方法实例小结
2019/07/05 Javascript
使用layui+ajax实现简单的菜单权限管理及排序的方法
2019/09/10 Javascript
python显示生日是星期几的方法
2015/05/27 Python
Python3 伪装浏览器的方法示例
2017/11/23 Python
Python中elasticsearch插入和更新数据的实现方法
2018/04/01 Python
Python爬虫 urllib2的使用方法详解
2019/09/23 Python
HTML5 解决苹果手机不能自动播放音乐问题
2017/12/27 HTML / CSS
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
美国猫狗药物和用品网站:PetCareRx
2017/01/05 全球购物
爱游人:Travelliker
2017/09/05 全球购物
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
第二层交换机和路由器的区别?第三层交换机和路由器的区别?
2013/05/23 面试题
AJAX的优缺点都有什么
2015/08/18 面试题
2015年行政人事部工作总结
2015/05/13 职场文书
消防宣传语大全
2015/07/13 职场文书
详解MySQL的主键查询为什么这么快
2022/04/03 MySQL
IDEA中sout快捷键无效问题的解决方法
2022/07/23 Java/Android
前端传参数进行Mybatis调用mysql存储过程执行返回值详解
2022/08/14 MySQL