¿Hay algún método para generar un UUID con go language?
(12)
Tengo un código que se ve así:
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)
Devuelve una cadena con una longitud de 32, pero no creo que sea un UUID válido. Si se trata de un UUID real, ¿por qué es un UUID y cuál es el propósito del código que modifica el valor de u[8]
y u[6]
?
¿Hay una mejor forma de generar UUID?
"crypto / rand" es un paquete multiplataforma para la generación de bytes aleatorios
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
}
Como parte de la especificación uuid, si genera un uuid de forma aleatoria, debe contener un "4" como el 13 ° carácter y un "8", "9", "a" o "b" en el 17 ( source ).
// 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
De la post Russ Cox:
No hay una biblioteca oficial Ignorando la comprobación de errores, parece que funcionaría bien:
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:])
Nota: En la versión original, pre Go 1, la primera línea era:
f, _ := os.Open("/dev/urandom", os.O_RDONLY, 0)
Here compila y ejecuta, solo /dev/urandom
devuelve todos los ceros en el patio de recreo. Debería funcionar bien localmente
En el mismo hilo hay otros métodos / referencias / paquetes encontrados.
El paquete gorand tiene un método UUID que devuelve un UUID de Versión 4 (generado aleatoriamente) en su representación de cadena canónica ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") y es compatible con RFC 4122.
También utiliza el paquete crypto / rand para garantizar la generación de UUID más criptográficamente segura en todas las plataformas compatibles con Go.
import "github.com/leonelquinteros/gorand"
func main() {
uuid, err := gorand.UUID()
if err != nil {
panic(err.Error())
}
println(uuid)
}
En Linux, puede leer desde /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))
}
¡Sin dependencias externas!
$ go run uuid.go
3ee995e3-0c96-4e30-ac1e-f7f04fd03e44
Esta biblioteca es nuestro estándar para generación y análisis de uuid:
FWIW, satori/go.uuid es el paquete de UUID más destacado para Go . Es compatible con las versiones UUID 1-5 y cumple con RFC 4122 y DCE 1.1.
import "github.com/satori/go.uuid"
u := uuid.NewV4()
La biblioteca go-uuid
uuid NO cumple con RFC4122. Los bits variantes no están configurados correctamente. Hubo varios intentos por parte de miembros de la comunidad para que esto se solucione, pero las solicitudes de extracción del arreglo no se aceptan.
Puede generar UUID utilizando la biblioteca Go uuid que reescribí en base a la biblioteca go-uuid
. Hay varias correcciones y mejoras. Esto se puede instalar con:
go get github.com/twinj/uuid
Puede generar UUID aleatorios (versión 4) con:
import "github.com/twinj/uuid"
u := uuid.NewV4()
El tipo de UUID devuelto es una interfaz y el tipo subyacente es una matriz.
La biblioteca también genera v1 UUID y genera correctamente los UUID v3 y 5. Hay varios métodos nuevos para ayudar con la impresión y el formateo, y también nuevos métodos generales para crear UUID basados en datos existentes.
Para Windows, recientemente hice esto:
// +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
}
Puede generar UUID utilizando la biblioteca go-uuid . Esto se puede instalar con:
go get github.com/nu7hatch/gouuid
Puede generar UUID aleatorios (versión 4) con:
import "github.com/nu7hatch/gouuid"
...
u, err := uuid.NewV4()
El tipo de UUID
devuelto es una matriz de 16 bytes, por lo que puede recuperar fácilmente el valor binario. También proporciona la representación estándar de cadena hexadecimal a través de su método String()
.
El código que también se parece a él también generará un UUID de versión 4 válida: la manipulación bit a bit que lleva a cabo al final establece la versión y los campos de variante del UUID para identificarlo correctamente como la versión 4 . Esto se hace para distinguir los UUID aleatorios de los que se generan a través de otros algoritmos (por ejemplo, los UUID de la versión 1 en función de su dirección y hora MAC).
Una implementación oficial de Google se encuentra actualmente en desarrollo pero aún no es estable: https://github.com/google/uuid
Parece que es la continuación de https://github.com/pborman/uuid de esta respuesta
La generación de un UUID de la versión 4 funciona de la siguiente manera: uuid, err := uuid.NewRandom()
u[8] = (u[8] | 0x80) & 0xBF // what''s the purpose ?
u[6] = (u[6] | 0x40) & 0x4F // what''s the purpose ?
Estas líneas sujetan los valores del byte 6 y 8 a un rango específico. rand.Read
devuelve bytes aleatorios en el rango 0-255
, que no son todos valores válidos para un UUID. Por lo que puedo decir, esto debería hacerse para todos los valores en la porción.
Si estás en Linux, alternativamente puedes llamar a /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)
}
Cuyos rendimientos:
$ go run uuid.go
dc9076e9-2fda-4019-bd2c-900a8284b9c4