Go 언어로 UUID를 생성하는 방법이 있습니까?
다음과 같은 코드가 있습니다.
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)
길이가 32 인 문자열을 반환하지만 유효한 UUID라고 생각하지 않습니다. 그것은 실제 UUID 인 경우, 이유는 UUID, 그리고 코드가 수정의 값의 목적은 무엇인가 u[8]
하고 u[6]
.
UUID를 생성하는 더 좋은 방법이 있습니까?
u[8] = (u[8] | 0x80) & 0xBF // what's the purpose ?
u[6] = (u[6] | 0x40) & 0x4F // what's the purpose ?
이 행은 바이트 6 및 8의 값을 특정 범위로 고정합니다. UUID에 대해 모두 유효한 값이 아닌 rand.Read
범위의 임의의 바이트를 반환합니다 0-255
. 내가 말할 수있는 한, 이것은 슬라이스의 모든 값에 대해 수행되어야합니다.
Linux를 사용하는 경우 /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)
}
결과 :
$ go run uuid.go
dc9076e9-2fda-4019-bd2c-900a8284b9c4
go-uuid 라이브러리를 사용하여 UUID를 생성 할 수 있습니다 . 다음과 함께 설치할 수 있습니다.
go get github.com/nu7hatch/gouuid
다음을 사용하여 임의 (버전 4) UUID를 생성 할 수 있습니다.
import "github.com/nu7hatch/gouuid"
...
u, err := uuid.NewV4()
반환 된 UUID
유형은 16 바이트 배열이므로 이진 값을 쉽게 검색 할 수 있습니다. 또한 String()
메서드 를 통해 표준 16 진 문자열 표현을 제공합니다 .
또한 코드는 유효한 버전 4 UUID를 생성하는 것처럼 보입니다. 마지막에 수행하는 비트 조작은 UUID의 버전 및 변형 필드를 설정하여 버전 4로 올바르게 식별합니다 . 이는 임의의 UUID를 다른 알고리즘 (예 : MAC 주소 및 시간을 기반으로 한 버전 1 UUID)을 통해 생성 된 것과 구별하기 위해 수행됩니다.
go-uuid
라이브러리는 RFC4122에 호환되지 않습니다. 변형 비트가 올바르게 설정되지 않았습니다. 커뮤니티 구성원이이 문제를 수정하려고 여러 번 시도했지만 수정에 대한 풀 요청이 수락되지 않았습니다.
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 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.
"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
}
You should use google/uuid https://github.com/google/uuid
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
id, err := uuid.NewUUID()
if err !=nil {
// handle error
}
fmt.Printf(id.String())
}
This package is RFC4122 and DCE 1.1 compliant
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())
There is an official implementation by Google: https://github.com/google/uuid
Generating a version 4 UUID works like this:
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
id := uuid.New()
fmt.Println(id.String())
}
Try it here: https://play.golang.org/p/6YPi1djUMj9
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.
In the same thread there are some other methods/references/packages found.
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 makes sure that the 13th character is "4"
u[6] = (u[6] | 0x40) & 0x4F
// this makes 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
:
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
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
}
This library is our standard for uuid generation and parsing:
https://github.com/pborman/uuid
참고URL : https://stackoverflow.com/questions/15130321/is-there-a-method-to-generate-a-uuid-with-go-language
'code' 카테고리의 다른 글
javascript / Node.js에서 시간을 어떻게 얻습니까? (0) | 2020.08.29 |
---|---|
URL에서 .html을 제거하는 방법? (0) | 2020.08.29 |
C #의 JSON 포맷터? (0) | 2020.08.29 |
CSS로 투명한 테두리를 만들려면 어떻게합니까? (0) | 2020.08.28 |
phpmyadmin으로 과거 mysql 쿼리를 볼 수있는 방법이 있습니까? (0) | 2020.08.28 |