web-dev-qa-db-fra.com

Existe-t-il une méthode pour générer un UUID avec le langage Go?

J'ai un code qui ressemble à ceci:

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)

Il renvoie une chaîne d'une longueur de 32, mais je ne pense pas que ce soit un UUID valide. S'il s'agit d'un UUID réel, pourquoi s'agit-il d'un UUID et quel est l'objectif du code qui modifie la valeur de u[8] et u[6].

Existe-t-il un meilleur moyen de générer des UUID?

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

Ces lignes fixent les valeurs des octets 6 et 8 à une plage spécifique. Rand.Read renvoie des octets aléatoires dans la plage 0-255, qui ne sont pas toutes des valeurs valides pour un UUID. Autant que je sache, cela devrait cependant être fait pour toutes les valeurs de la tranche.

Si vous êtes sur Linux, vous pouvez aussi appeler /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)
}

Quels rendements:

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

Vous pouvez générer des UUID à l'aide de la bibliothèque go-uuid . Ceci peut être installé avec:

go get github.com/nu7hatch/gouuid

Vous pouvez générer des UUID aléatoires (version 4) avec:

import "github.com/nu7hatch/gouuid"

...

u, err := uuid.NewV4()

Le type UUID renvoyé est un tableau de 16 octets. Vous pouvez ainsi extraire facilement la valeur binaire. Il fournit également la représentation standard des chaînes hexadécimales via sa méthode String().

Le code que vous avez semble également générer une UUID valide pour la version 4: la manipulation binaire effectuée à la fin définit correctement les champs de version et de variante de l'UUID l'identifie comme version 4 . Ceci est fait pour distinguer les UUID aléatoires de ceux générés via d’autres algorithmes (par exemple, des UUID de version 1 basés sur votre adresse MAC et votre heure).

88
James Henstridge

La bibliothèque go-uuid N'est PAS conforme à RFC4122. Les bits de variante ne sont pas définis correctement. Des membres de la communauté ont tenté à plusieurs reprises de corriger ce problème, mais les demandes d'extraction du correctif ne sont pas acceptées.

Vous pouvez générer des UUID à l'aide de la bibliothèque Go uuid que j'ai récrite en fonction de la bibliothèque go-uuid. Il existe plusieurs correctifs et améliorations. Ceci peut être installé avec:

go get github.com/twinj/uuid

Vous pouvez générer des UUID aléatoires (version 4) avec:

import "github.com/twinj/uuid"

u := uuid.NewV4()

Le type UUID renvoyé est une interface et le type sous-jacent est un tableau.

La bibliothèque génère également des UUID v1 et génère correctement les vU et 5 UUID. Il existe plusieurs nouvelles méthodes d'aide à l'impression et au formatage, ainsi que de nouvelles méthodes générales pour créer des UUID basés sur des données existantes.

69
twinj

"crypto/Rand" est un paquet multiplateforme pour le générateur d'octets aléatoires

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
}
47
Ken Cloud

Vous devez utiliser 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())
}

Ce paquet est conforme aux normes RFC4122 et DCE 1.1

27
stwykd

gofrs/uuid est le remplacement de satori/go.uuid , qui est le le paquet UUID le plus étoilé pour Go . Il prend en charge les versions UUID 1 à 5 et est conforme aux normes RFC 4122 et DCE 1.1.

import "github.com/gofrs/uuid"

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

De Russ Cox's post :

Il n'y a pas de bibliothèque officielle. En ignorant les erreurs, cela semble fonctionner correctement:

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:])

Remarque: dans la version originale, avant Go 1, la première ligne était la suivante:

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

Ici il compile et exécute, seulement /dev/urandom renvoie tous les zéros dans la cour de récréation. Devrait bien fonctionner localement.

Dans le même fil, d'autres méthodes/références/packages ont été trouvés.

13
zzzz

Il existe une implémentation officielle par Google: https://github.com/google/uuid

La génération d'un UUID version 4 fonctionne comme suit:

package main

import (
    "fmt"
    "github.com/google/uuid"
)

func main() {
    id := uuid.New()
    fmt.Println(id.String())
}

Essayez-le ici: https://play.golang.org/p/6YPi1djUMj9

12
shutefan

Dans le cadre de la spécification uuid, si vous générez un uuid à partir d’aléatoire, il doit contenir un "4" comme 13ème caractère et un "8", "9", "a" ou "b" dans le 17ème ( 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 
7
eric chiang

Le package gorand a une méthode UUID qui renvoie un UUID version 4 (généré aléatoirement) dans sa représentation sous forme de chaîne canonique ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") et sa conformité à la norme RFC 4122.

Il utilise également le package crypto/Rand pour garantir la génération la plus sécurisée d’UUID sur toutes les plates-formes prises en charge par Go.

import "github.com/leonelquinteros/gorand"

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

    println(uuid)
} 
4
peiiion

Sous Linux, vous pouvez lire à partir de /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))
}

Aucune dépendance externe!

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

Cette bibliothèque est notre standard pour la génération et l'analyse uuid:

https://github.com/pborman/uuid

0
James McGill