다음과 같은 코드가 있습니다.
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에 호환되지 않습니다. 변형 비트가 올바르게 설정되지 않았습니다. 커뮤니티 구성원이이 문제를 수정하려고 여러 번 시도했지만 수정에 대한 풀 요청이 수락되지 않았습니다.
라이브러리를 기반으로 다시 작성한 Go uuid 라이브러리를 사용하여 UUID를 생성 할 수 있습니다 go-uuid
. 몇 가지 수정 및 개선 사항이 있습니다. 다음과 함께 설치할 수 있습니다.
go get github.com/twinj/uuid
다음을 사용하여 임의 (버전 4) UUID를 생성 할 수 있습니다.
import "github.com/twinj/uuid"
u := uuid.NewV4()
반환 된 UUID 유형은 인터페이스이고 기본 유형은 배열입니다.
라이브러리는 또한 v1 UUID를 생성하고 v3 및 5 UUID를 올바르게 생성합니다. 인쇄 및 서식 지정에 도움이되는 몇 가지 새로운 방법과 기존 데이터를 기반으로 UUID를 만드는 새로운 일반 방법이 있습니다.
답변
“crypto / rand”는 임의의 바이트 생성을위한 크로스 플랫폼 패키지입니다.
package main
import (
"crypto/rand"
"fmt"
)
// Note - NOT RFC4122 compliant
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
}
답변
Google의 공식 구현이 있습니다 : https://github.com/google/uuid
버전 4 UUID 생성은 다음과 같이 작동합니다.
package main
import (
"fmt"
"github.com/google/uuid"
)
func main() {
id := uuid.New()
fmt.Println(id.String())
}
여기에서 사용해보세요 : https://play.golang.org/p/6YPi1djUMj9
답변
gofrs / UUID는 대한 대체 SATORI / go.uuid 는 IS, 이동에 가장 별표 UUID 패키지 . UUID 버전 1-5를 지원하며 RFC 4122 및 DCE 1.1을 준수합니다.
import "github.com/gofrs/uuid"
// Create a Version 4 UUID, panicking on error
u := uuid.Must(uuid.NewV4())
답변
Russ Cox의 게시물에서 :
공식 도서관이 없습니다. 오류 검사를 무시하면 정상적으로 작동하는 것 같습니다.
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:])
참고 : 원래 Go 1 이전 버전에서 첫 번째 줄은 다음과 같습니다.
f, _ := os.Open("/dev/urandom", os.O_RDONLY, 0)
여기서 컴파일하고 실행 /dev/urandom
하며 플레이 그라운드의 모든 0 만 반환합니다. 로컬에서 잘 작동합니다.
같은 스레드에는 몇 가지 다른 메서드 / 참조 / 패키지가 있습니다.