Есть ли способ создать 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?

642   12  

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
}

эта библиотека является нашим стандартом для генерации и анализа uuid:

https://github.com/pborman/uuid

Comments

    Ничего не найдено.