GoLang中生成UUID唯一标识的实现

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)
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 聊聊golang中多个defer的执行顺序

    golang 中多个 defer 的执行顺序 引用 Ture Go 中的一个示例: package main import "fmt" func main() { fmt.Println("counting") for i := 0; i < 10; i++ { defer fmt.Println(i) } fmt.Println("done") } 程序执行结果为: counting done 9 8 7 6 5 4 3 2 1 0 从结

  • golang中的并发和并行

    golang中默认使用一个CPU,这时程序无法并发,只能是并发.因为始终只有一个CPU在运行. package main import ( "fmt" "runtime" ) //并发和并行 var quit chan int = make(chan int) func loop() { for i := 0; i < 100; i++ { //为了观察,跑多些 fmt.Printf("%d ", i) } quit <- 0 } f

  • golang 实现并发求和

    使用golang并发求和,作为对golang并发的一个练习. 为了验证结果的正确性,要给出最传统的版本: func sum1(data []int) int { s := 0 l := len(data) for i := 0; i < l; i++ { s += data[i] } return s } 第二种方法 使用N个goroutine, 然后将N个分段的和写入N个channel中: func sum2(data []int) int { s := 0 l := len(data) co

  • 关于golang高并发的实现与注意事项说明

    一.并发的意义 并发的意义就是让 一个程序同时做多件事情,其目的只是为了能让程序同时做另一件事情而已,而不是为了让程序运行的更快(如果是多核处理器,而且任务可以分成相互独立的部分,那么并发确实可以让事情解决的更快). golang从语言级别上对并发提供了支持,而且在启动并发的方式上直接添加了语言级的关键字,不必非要按照固定的格式来定义线程函数,也不必因为启动线程的时候只能给线程函数传递一个参数而烦恼. 二.并发的启动 go的并发启动非常简单,几乎没有什么额外的准备工作,要并发的函数和一般的函数没

  • golang实现java uuid的序列化方法

    目前只实现了java生成的固定的uuid:85bb94b8-fd4b-4e1c-8f49-3cedd49d8f28的序列化 package main import ( "encoding/binary" "encoding/json" "fmt" "log" "os" "strings" "time" "github.com/Shopify/sarama&q

  • 基于Golang 高并发问题的解决方案

    Golang 高并发问题的解决 Golang在高并发问题上,由于协程的使用,相对于其他编程语言,已经有了很大的优势,即相同的配置上,Golang可以以更低的代价处理更多的线程,同样的线程数,占用更低的资源!及时这样,只是解决了一部分问题而已,因为在每个协程里,处理逻辑还是会有问题. 高并发时,还是要考虑服务器所能承受的最大压力,数据库读取时的io问题,连接数问题,带宽问题等等 研究了一下并发解决方案,在此记录一下 参考文章:Handling 1 Million Requests per Minu

  • 使用golang编写一个并发工作队列

    其实golang用一个函数可以构建一个并发队列,现在编写一个灵活可控的队列程序 先定义一个工作 type Worker struct { ID int RepJobs chan int64 SM *SM quit chan bool } 包含了workid和执行任务的id,上面的SM只是任务具体内容,这个和具体业务相关,大家自己编写自己的SM业务逻辑 然后定义工作池 type workerPool struct { workerChan chan *Worker workerList []*Wo

  • Golang全局变量加锁的问题解决

    如果全局变量只读取 那自然是不需要加锁的 如果全局变量多进程读,多进程写,那自然是需要加读写锁的 但是如果全局变量只有一个进程写,其他进程读呢? 如果采用COW的方式,写进程只是通过单次赋值的方式来更新变量,是否就可以不加锁了呢? 就第三种情况而言: 当然我们通过 go build -race 或者 go run -race 就会出现 WARNING: DATA RACE. 但是出现 data race 就证明一定有问题么? 其实核心点在于这个赋值是否是原子的.也就是说是否存在 p1 = p2

  • GoLang中生成UUID唯一标识的实现

    1.什么是UUID UUID简介 通用唯一识别码(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为自由软件基金会组织在分散式计算环境领域的一部份. UUID的目的,是让分散式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定. 如此一来,每个人都可以创建不与其它人冲突的UUID. 在这样的情况下,就不需考虑数据库创建时的名称重复问题.目前最广泛应用的UUID,是微软公司的全局唯一标识符(GUID),而其他重要

  • 浅谈JAVA如何生成UUID唯一标识

    1.UUID 简介 UUID 含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准. 也是被开源软件基金会 (Open Software Foundation, OSF)的组织应用在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部分. UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定. 如此一来,每个人都可以建立不与其它人

  • PHP中生成UUID自定义函数分享

    UUID 全称是 Universally unique identifier,它是一种识别符,使用任意的计算机都可以生成,不需要一个中央数据库进行管理,即可以保证几乎没有重复的几率.而 UUID 的值域之大,据说给世界上每一粒沙子分配一个 UUID,也不会有重复的. 最近在改 WordPress 的代码,需要用到 UUID.但是,PHP 中居然没有生成 UUID 的函数,只好自己写一个. if (!function_exists('com_create_guid')) { function co

  • Golang中生成随机字符串并复制到粘贴板的方法

    前段时间在生活中偶尔需要对某些文件进行重命名,而且是随机名字,刚 开始是手动重命名然后在键盘上胡乱打一些字母数字,时间长了发现也挺麻烦的,于是想到能不能用golang实现这个功能并且自动把生成的字符串 复制到粘贴板,然后生成exe文件,要用的是直接鼠标双击就行.说干就干. 网上搜了些相关资料,于是写了出来. 安装必要的库 go get github.com/atotto/clipboard 代码实现 package main import ( "fmt" "github.co

  • 浅谈Java生成唯一标识码的三种方式

    目录 前言 正文 UUID实现唯一标识码 SnowFlake实现唯一标识码 通过时间工具生成带有业务标示的唯一标识码 前言 我们经常会遇到这样的场景,需要生成一个唯一的序列号来表明某一个数据的唯一性,在单节点的应用中我们可以简单地使用一个自增的整型来实现实现,但是在分布式情况下这个方式却存在冲突的可能性,那么有什么办法我们可以生成一个唯一的序列号呢,并且如果想使得这个序列号也能展示一些业务信息呢? 正文 UUID实现唯一标识码 UUID 的目的是让分布式系统中的所有元素,都能有唯一的辨识资讯,而

  • Python使用uuid库生成唯一标识ID

    uuid是128位的全局唯一标识符(univeral unique identifier),通常用32位的一个字符串的形式来表现.有时也称guid(global unique identifier).python中自带了uuid模块来进行uuid的生成和管理工作. python中的uuid模块基于信息如MAC地址.时间戳.命名空间.随机数.伪随机数来uuid.具体方法有如下几个: uuid.uuid1() 基于MAC地址,时间戳,随机数来生成唯一的uuid,可以保证全球范围内的唯一性. uuid

  • Python标准库uuid模块(生成唯一标识)详解

    目录 UUID格式组成 Python 中的uuid 模块 uuid1() 中的getnode() UUID实际应用 UUID 的劣势 参考资料: 总结 UUID (Universally Unique Identifier,通用唯一标识)是一个128位的用于计算机系统中以识别信息的数目,虽然生成UUID的概率不为零,但是无限接近零,因此可以忽略不记,如此一来,每个人都可以建立不与其他人冲突的UUID. UUID格式组成 规范的文本中,UUID的十六个八位字节标识位32个十六进制(基数16)数字,

  • Java中生成唯一ID的方法示例

    有时我们不依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,这时就需要用程序来生成一个唯一的全局ID. UUID 从Java 5开始, UUID 类提供了一种生成唯一ID的简单方法.UUID是通用唯一识别码 (Universally Unique Identifier)的缩写,UUID来源于OSF(Open Software Foundation,开源软件基金会)的DCE(Distributed Computing Environment,分布式计算环境)规范.UU

  • 详解php中生成标准uuid(guid)的方法

    UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的. 通常平台 会提供生成UUID的API.UUID按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址.纳秒级时间.芯片ID码和许多可能的数字. 由以 下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相 同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在

  • iOS获取设备唯一标识的8种方法

    8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可以改变设备的 UDID),移动网络可以利用 UDID 来识别移动设备. 许多开发者把 UDID 跟用户的真实姓名.密码.住址.其它数据关联起来,网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据,同时大部分应用确实在频繁传输 UDID 和私人信息. 为了避免集体诉讼,苹果最终决

随机推荐