Есть ли способ создать UUID с помощью языка go
у меня есть код, который выглядит так:
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].
есть ли лучший способ генерации UUIDs?
12 ответов:
u[8] = (u[8] | 0x80) & 0xBF // what's the purpose ? u[6] = (u[6] | 0x40) & 0x4F // what's the purpose ?эти строки зажимают значения байта 6 и 8 в определенном диапазоне.
rand.Readвозвращает случайные байты в диапазоне0-255, которые не все допустимые значения для UUID. Насколько я могу судить, это должно быть сделано для всех значений хоть кусочек.если вы находитесь на 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
вы можете генерировать UUIDs с помощью go-uuid библиотека. Это может быть установлено с:
go get github.com/nu7hatch/gouuidвы можете генерировать случайные (версия 4) UUIDs с:
import "github.com/nu7hatch/gouuid" ... u, err := uuid.NewV4()возвращенный
UUIDтип-это 16-байтовый массив, поэтому вы можете легко получить двоичное значение. Он также предоставляет стандартное шестнадцатеричное строковое представление через егоString()метод.код у вас также выглядит так, как будто он также будет генерировать действительную версию 4 UUID: побитовое манипуляции, которые вы выполняете в конце, устанавливают поля версии и варианта UUID правильно идентифицируйте его как версию 4. Это делается для того, чтобы отличить случайные UUID от тех, которые генерируются с помощью других алгоритмов (например, UUID версии 1 на основе вашего MAC-адреса и времени).
The
go-uuidбиблиотека не соответствует RFC4122. Биты вариантов установлены неправильно. Было несколько попыток членов сообщества исправить это, но запросы на исправление не принимаются.вы можете генерировать UUID, используя библиотеку Go uuid, которую я переписал на основе
go-uuidбиблиотека. Есть несколько исправлений и улучшений. Это может быть установлено с:go get github.com/twinj/uuidвы можете генерировать случайные (версия 4) UUIDs с:
import "github.com/twinj/uuid" u := uuid.NewV4()возвращаемый тип UUID является интерфейсом, а базовый тип-массивом.
библиотека также создает В1 идентификаторы UUID и правильно формирует V3 и 5 идентификаторов UUID. Есть несколько новых методов, чтобы помочь с печатью и форматированием, а также новые общие методы для создания UUIDs на основе существующих данных.
"crypto/rand" - это кросс-платформенный pkg для генерации случайных байтов
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 }
gofrs / uuid - это замена Сатори / go.uuid, который является самый звездный пакет UUID для Go. Он поддерживает 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())
от Расса Кокса post:
нет никакой официальной библиотеки. Игнорирование проверки ошибок, это кажется, что это будет работать нормально:
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:])Примечание: В оригинале, pre Go 1 Версия первая строка была:
f, _ := os.Open("/dev/urandom", os.O_RDONLY, 0)здесь он компилируется и выполняется, только
/dev/urandomвозвращает все нули на детской площадке. Должно работать нормально локально.в том же потоке есть некоторые другие найдены методы / ссылки / пакеты.
как часть спецификации uuid, если вы генерируете uuid из случайного, он должен содержать "4 "в качестве 13-го символа и" 8"," 9"," a "или" b " в 17-м (источник).
// 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
на gorand пакет имеет метод UUID, который возвращает UUID версии 4 (случайно сгенерированный) в своем каноническом строковом представлении ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"), и он совместим с RFC 4122.
Он также использует пакет crypto/rand для обеспечения наиболее криптографически безопасного поколения UUID на всех платформах, поддерживаемых Go.
import "github.com/leonelquinteros/gorand" func main() { uuid, err := gorand.UUID() if err != nil { panic(err.Error()) } println(uuid) }
на Linux вы можете читать от
/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)) }нет внешних зависимостей!
$ go run uuid.go 3ee995e3-0c96-4e30-ac1e-f7f04fd03e44
официальная реализация Google в настоящее время находится в стадии разработки, но еще не стабильна:https://github.com/google/uuid
похоже, это продолжение https://github.com/pborman/uuid от ответ
генерация UUID версии 4 работает следующим образом:
uuid, err := uuid.NewRandom()
для Windows, я сделал недавно это:
// +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 }
Comments