Is there a method to generate a UUID with go language

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Is there a method to generate a UUID with go language



I have code that looks like this:


u := make(byte, 16)
_, err := rand.Read(u)
if err != nil
return


u[8] = (u[8] | 0x80) & 0xBF // what does this do?
u[6] = (u[6] | 0x40) & 0x4F // what does this do?

return hex.EncodeToString(u)



It returns a string with a length of 32, but I don't think it is a valid UUID. If it is a real UUID, why is it a UUID, and what is the purpose of the code that modifies the value of u[8] and u[6].


u[8]


u[6]



Is there a better way of generating UUIDs?




12 Answers
12


u[8] = (u[8] | 0x80) & 0xBF // what's the purpose ?
u[6] = (u[6] | 0x40) & 0x4F // what's the purpose ?



These lines clamp the values of byte 6 and 8 to a specific range. rand.Read returns random bytes in the range 0-255, which are not all valid values for a UUID. As far as I can tell, this should be done for all the values in the slice though.


rand.Read


0-255



If you are on linux, you can alternatively call /usr/bin/uuidgen.


/usr/bin/uuidgen


package main

import (
"fmt"
"log"
"os/exec"
)

func main()
out, err := exec.Command("uuidgen").Output()
if err != nil
log.Fatal(err)

fmt.Printf("%s", out)



Which yields:


$ go run uuid.go
dc9076e9-2fda-4019-bd2c-900a8284b9c4





Notably, this approach is slow; on a 2012 MacBook Air this strategy can produce only 170 uuids/second.
– Jay Taylor
Aug 25 '13 at 22:35






And using the nu7hatch/gouuid library, I was able to generate 172,488 uuids/second.
– Jay Taylor
Aug 25 '13 at 23:09





Good explanation of the u[6] and u[8] bytes.
– chowey
May 6 '14 at 17:26


u[6]


u[8]





On my system (Ubuntu 15.10) I also needed to run the command output through strings.Trim(string(out)) to remove the newline character, otherwise it was inputted up as a trailing ? character in the filesystem.
– Egg
Feb 24 '16 at 1:06





Calling an external program which may or may not exist is an awful way to do this fairly simple task.
– Timmmm
Apr 4 '16 at 10:06



You can generate UUIDs using the go-uuid library. This can be installed with:


go get github.com/nu7hatch/gouuid



You can generate random (version 4) UUIDs with:


import "github.com/nu7hatch/gouuid"

...

u, err := uuid.NewV4()



The returned UUID type is a 16 byte array, so you can retrieve the binary value easily. It also provides the standard hex string representation via its String() method.


UUID


String()



The code you have also looks like it will also generate a valid version 4 UUID: the bitwise manipulation you perform at the end set the version and variant fields of the UUID to correctly identify it as version 4. This is done to distinguish random UUIDs from ones generated via other algorithms (e.g. version 1 UUIDs based on your MAC address and time).





@ErikAigner: Because often using a library is better than doing it yourself.
– Flimzy
Aug 30 '15 at 1:19





@ErikAigner As long as it is 50 lines I do not have to think about, write and test, I'll take them thank you.. I have other stuff to do then reinvent the wheel.
– RickyA
Nov 2 '15 at 14:48






This library looks like it is not actually RFC4122 compliant: github.com/nu7hatch/gouuid/issues/28 (currently open issue as of 2/1/2016)
– Charles L.
Feb 1 '16 at 20:21





@ErikAigner i just find that riduclous. No one reinvents stuff thats done already unless you can do better or need something specific to your program, if you inspect the code and see it does it well why bother do it yourself - not only do you waste development time and cost, you are also potentially going to bring in bugs or simply wrong implementations if you don't know completely what you are doing, these libraries are usually made people who do know what they are doing. It is not rookie to use third party libraries, its only rookie to just assume it works and not inspect the code first..
– Sir
Oct 31 '17 at 21:50






Oh im sorry i forgot every company ever reprograms absolutely everything, makes their own editors, operating systems, their own programming language because why use Go when you should know how to make your own right?. No one does. At the end of the day you will be using some one else's code some where unless you have no concept of time/money saving as a business. Its just totally dumb to do it twice over. Many companies use code with MIT licenses and then modify to their needs. Clearly you don't have much experience working in different companies.
– Sir
Nov 2 '17 at 19:16




The go-uuid library is NOT RFC4122 compliant. The variant bits are not set correctly. There have been several attempts by community members to have this fixed but pull requests for the fix are not being accepted.


go-uuid



You can generate UUIDs using the Go uuid library I rewrote based on the go-uuid library. There are several fixes and improvements. This can be installed with:


go-uuid


go get github.com/twinj/uuid



You can generate random (version 4) UUIDs with:


import "github.com/twinj/uuid"

u := uuid.NewV4()



The returned UUID type is an interface and the underlying type is an array.



The library also generates v1 UUIDs and correctly generates v3 and 5 UUIDs. There are several new methods to help with printing and formatting and also new general methods to create UUIDs based off of existing data.





I like this package. I've officially adopted it for all my applications. I found that the nu7hatch package wasn't RFC4122-compliant.
– Richard Eng
Aug 19 '14 at 16:47





+1 Agreed, the updates and printing/formatting extensions already included.
– eduncan911
Sep 10 '14 at 16:53





Disclaimer missing? :p
– chakrit
Sep 22 '14 at 7:23





What is the library "below"? You should avoid using above and below on SO as that can change quite quickly.
– inf
Jan 18 '15 at 7:10





There's also another equivallent, satori/go.uuid. Didn't try it yet but I am going to use it as a replacement of nu7hatch dead project...
– shadyyx
Apr 7 '16 at 13:06



"crypto/rand" is cross platform pkg for random bytes generattion


package main

import (
"crypto/rand"
"fmt"
)

func pseudo_uuid() (uuid string)

b := make(byte, 16)
_, err := rand.Read(b)
if err != nil
fmt.Println("Error: ", err)
return


uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])

return





pseudo_uuid because it is missing the non-random identifiers like MAC address and whatever else RFC4122 specified? So it's actually more random.
– Xeoncross
Apr 21 '17 at 21:27


pseudo_uuid





good answer; I've expanded it at stackoverflow.com/a/48134820/1122270, and I think a lot of folks actually don't need to use UUIDs specifically (nor the sha1/sha256 that I thought I need to use for my own random-id problem), but simply want something random and unique, and your sample provides a good start for a solution
– cnst
Jan 7 at 6:26



gofrs/uuid is the replacement for satori/go.uuid, which is the most starred UUID package for Go. It supports UUID versions 1-5 and is RFC 4122 and DCE 1.1 compliant.


import "github.com/gofrs/uuid"

// Create a Version 4 UUID, panicking on error
u := uuid.Must(uuid.NewV4())



From Russ Cox's post:



There's no official library. Ignoring error checking,
this seems like it would work fine:


f, _ := os.Open("/dev/urandom")
b := make(byte, 16)
f.Read(b)
f.Close()
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])



Note: In the original, pre Go 1 version the first line was:


f, _ := os.Open("/dev/urandom", os.O_RDONLY, 0)



Here it compiles and executes, only /dev/urandom returns all zeros in the playground. Should work fine locally.


/dev/urandom



In the same thread there are some other methods/references/packages found.





This won't generate a valid UUID though: version 4 UUIDs (the type based on random data) require a few bits to be set in a certain way to avoid conflicting with the non-random UUID formats.
– James Henstridge
Feb 28 '13 at 11:21





Better to use import "crypto/rand" in my opinion, but +1 for uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]). Combined with the OP's code, and this works great.
– chowey
May 6 '14 at 17:25


import "crypto/rand"


uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])





Using the crypto/rand package: play.golang.org/p/7JJDx4GL77. zzzz's code does what crypt/rand does, except that it also covers platforms that don't support /dev/urandom (Windows).
– Drew
Nov 4 '14 at 6:09





It should be noted that this is platform specific
– Dan Esparza
Oct 27 '16 at 18:03





@JamesHenstridge - 99.9999% of the time, no one wants to know what version UUID it is. They just want an ID that's unique. The spec over complates what is a very simple problem.
– Matt
Aug 30 '17 at 23:25




As part of the uuid spec, if you generate a uuid from random it must contain a "4" as the 13th character and a "8", "9", "a", or "b" in the 17th (source).


// this make sure that the 13th character is "4"
u[6] = (u[6] | 0x40) & 0x4F
// this make sure that the 17th is "8", "9", "a", or "b"
u[8] = (u[8] | 0x80) & 0xBF



The gorand package has a UUID method that returns a Version 4 (randomly generated) UUID in its canonical string representation ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") and it's RFC 4122 compliant.



It also uses the crypto/rand package to ensure the most cryptographically secure generation of UUIDs across all platforms supported by Go.


import "github.com/leonelquinteros/gorand"

func main()
uuid, err := gorand.UUID()
if err != nil
panic(err.Error())


println(uuid)



On Linux, you can read from /proc/sys/kernel/random/uuid:


/proc/sys/kernel/random/uuid


package main

import "io/ioutil"
import "fmt"

func main()
u, _ := ioutil.ReadFile("/proc/sys/kernel/random/uuid")
fmt.Println(string(u))



No external dependencies!


$ go run uuid.go
3ee995e3-0c96-4e30-ac1e-f7f04fd03e44





Downvoted because directly depending on a host-platform in a programming language that's used for multi-platform applications is worse than an external dependency.
– Byebye
Aug 7 at 8:08



An official implementation by Google is currently under development but not stable yet: https://github.com/google/uuid



Looks like it's the continuation of https://github.com/pborman/uuid from this answer



Generating a version 4 UUID works like this:
uuid, err := uuid.NewRandom()


uuid, err := uuid.NewRandom()



For Windows, I did recently this:


// +build windows

package main

import (
"syscall"
"unsafe"
)

var (
modrpcrt4 = syscall.NewLazyDLL("rpcrt4.dll")
procUuidCreate = modrpcrt4.NewProc("UuidCreate")
)

const (
RPC_S_OK = 0
)

func NewUuid() (byte, error)
var uuid [16]byte
rc, _, e := syscall.Syscall(procUuidCreate.Addr(), 1,
uintptr(unsafe.Pointer(&uuid[0])), 0, 0)
if int(rc) != RPC_S_OK
if e != 0
return nil, error(e)
else
return nil, syscall.EINVAL


return uuid[:], nil





Downvoted because directly depending on a host-platform in a programming language that's used for multi-platform applications is worse than an external dependency.
– Byebye
Aug 7 at 8:10





@Byebye, I wonder why you consider yourself an authority to decide what "is worse" (and what is not) to skim through all the answers given to this question and downvote all which are "system-dependent"? These answers were given to a) widen the horizon of all possible choices, and b) collectively present a complete picture. So please stop childishly "playing SO" and put some thought before you action.
– kostix
Aug 7 at 8:50






Short answer. Writing maintainable code. Your answer cannot be ported to a different platform. So if the OP would choose to move their application to another platform the application would break. I've had my fair share of people who wrote platform dependent code where it is totally unnecessary and it creates more trouble then it's worth. You don't write code for just yourself. You write code for the people who will maintain it after you're gone. That's why this answer is not appropriate. No reason to resort to ad hominems and call me childish.
– Byebye
Aug 7 at 9:12





@Byebye, I overreacted, so please excuse me for the attack. I'm not convinced of your reasons, still, but supposedly it's that "let's agree to disagree" case.
– kostix
Aug 7 at 9:22



This library is our standard for uuid generation and parsing:



https://github.com/pborman/uuid






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS