Generar UUID aleatorio


15

Necesito un UUID Tu trabajo es generar uno.

El UUID canónico (Universal Unique IDentifier) ​​es un número hexadecimal de 32 dígitos con guiones insertados en ciertos puntos. El programa debe generar 32 dígitos hexadecimales (128 bits), en forma de xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx(8-4-4-4-12 dígitos), donde xhay un número hexadecimal aleatorio. Suponiendo que el PRNG de su idioma es perfecto, todas las salidas válidas deben tener la misma probabilidad de ser generadas.

TL; DR

Genere 32 dígitos hexadecimales aleatorios en el formulario 8-4-4-4-12 dígitos del . El código más corto gana.

EDITAR: debe ser hexadecimal. Generar siempre decimal solo no es válido. EDIT 2: sin incorporados. Estos no son GUID, solo dígitos hexadecimales genéricos.


Salida de ejemplo:

ab13901d-5e93-1c7d-49c7-f1d67ef09198
7f7314ca-3504-3860-236b-cface7891277
dbf88932-70c7-9ae7-b9a4-f3df1740fc9c
c3f5e449-6d8c-afe3-acc9-47ef50e7e7ae
e9a77b51-6e20-79bd-3ee9-1566a95d9ef7
7b10e43c-3c57-48ed-a72a-f2b838d8374b

La entrada y las lagunas estándar no están permitidas.


Este es el , por lo que gana el código más corto. Además, siéntase libre de pedir aclaraciones.


55
Parece una versión menos estricta de codegolf.stackexchange.com/q/32309/14215
Geobits

99
"Estos ejemplos no son aleatorios. Intenta atribuir cierta importancia". Qué significa eso?
Alex A.

3
En realidad, uno no necesita números hexadecimales, 10 bases también pueden ser aleatorios. Por ejemplo, 12345678-1234-1234-1234-123456789012debería ser un UUID válido (¿o es necesario algún dígito hexadecimal?). ¿Consideras esto una escapatoria?
Voitcus

3
El título y la primera oración sugieren que desea un UUID canónico, y los ejemplos dados parecen seguir las especificaciones para UUID, pero en realidad parece que está pidiendo algo más.
Peter Taylor

3
Me siento obligado a señalar que el UUID de la versión 4 (aleatorio) tiene un formato requerido de xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx dónde yes uno de [89AB]. En el momento de este comentario, ninguna de las respuestas (excepto C # que utiliza una biblioteca incorporada) está garantizada para producir un UUID aleatorio válido (y en realidad, es muy probable que no produzca uno).

Respuestas:


11

Pyth, 20 bytes

j\-msm.HO16*4hdj83 3

Demostración.

Codifica [1, 0, 0, 0, 2]como 83 en la base 3, luego agrega uno y se multiplica por cuatro para obtener la longitud de cada segmento. Luego crea dígitos hexadecimales y se une en guiones.


8

Julia, 80 bytes

h=hex(rand(Uint128),32)
print(h[1:8]"-"h[9:12]"-"h[13:16]"-"h[17:20]"-"h[21:32])

Genere un entero aleatorio de 128 bits, obtenga su representación hexadecimal como una cadena rellenada con 32 dígitos y divídala en segmentos unidos con guiones.

¡Gracias a ConfusedMr_C y kvill por su ayuda!


8

CJam, 26 25 bytes

8 4__C]{{Gmr"%x"e%}*'-}/;

Pruébelo en línea en el intérprete de CJam .

Cómo funciona

8 4__C]{              }/   For each I in [8 4 4 4 12]:
        {         }*         Do I times:
         Gmr                   Pseudo-randomly select an integer between 0 and 15.
            "%x"e%             Apply hexadecimal string formatting.
                    '-       Push a hyphen-minus.
                        ;  Discard the last hyphen-minus.

5

PowerShell, 77 69 67 bytes

((8,4,4,4,12)|%{((1..$_)|%{'{0:X}'-f(random(16))})-Join""})-Join"-"

editar: parens extraños:

((8,4,4,4,12)|%{((1..$_)|%{('{0:X}'-f(random(16)))})-Join""})-Join"-"

editar: fue capaz de eliminar el .Trim final ("-") del original:

(((8,4,4,4,12)|%{((1..$_)|%{('{0:X}'-f(random(16)))})+"-"})-Join"").Trim("-")

Puede ser más claro con algo de espacio en blanco dada la naturaleza de las banderas (-f y -Join). Todavía me gustaría perder el Trim final ("-"):

(((8,4,4,4,12)|%{((1..$_)|%{('{0:X}' -f (random(16)))}) + "-"}) -Join "").Trim("-")

O, usando la funcionalidad incorporada (ala la respuesta C # anterior)

'{0}'-f[System.Guid]::NewGuid()

Sin embargo, parece un pequeño atajo, incluso si viene en 31 bytes.


61 byte:(8,4,4,4,12|%{-join(1..$_|%{'{0:X}'-f(random(16))})})-join'-'
mazzy

5

Python 2, 86 84 bytes

from random import*;print'-'.join('%%0%ix'%i%randint(0,16**i-1)for i in[8,4,4,4,12])

Esto encadena los formateadores de cadenas para hacer que Python formatee los números hexadecimales de forma exclusiva para cada segmento.

Sin golf:

import random

final = []
for i in [8, 4, 4, 4, 12]:               # Iterate through every segment
    max = (16 ** i) - 1                  # This is the largest number that can be
                                         # represented in i hex digits
    number = random.randint(0, max)      # Choose our random segment
    format_string = '%0' + str(i) + 'x'  # Build a format string to pad it with zeroes
    final.append(format_string % number) # Add it to the list

print '-'.join(final)                    # Join every segment with a hyphen and print

Esto podría mejorar, pero estoy orgulloso.



4

PHP, 69 72 75 bytes

foreach([8,4,4,4,12]as$c)$r[]=rand(".1e$c","1e$c");echo join('-',$r);

Esto no genera dígitos hexadecimales ( a, ... f). Están permitidos, pero no son requeridos por el cuerpo de la pregunta.

Ningún grupo de dígitos comienza con 0 (tampoco es obligatorio).

editar: guardado 3 bytes gracias a @IsmaelMiguel


Eso parece un bi de más de 32 bytes.
isaacg

@isaacg sí, lo siento, mi error
Voitcus

Deberías usar join()en su lugar.
Ismael Miguel

3

C #, 65 bytes

using System;class C{void Main(){Console.Write(Guid.NewGuid());}}

editar: ¡Sí! C # es más corto que otro lenguaje (además de Java) :)


1
Creo que esto se considera una escapatoria estándar ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings

1
Creo que esto no se considera un vacío legal estándar: como puede ver, la solicitud de abandonar esto solo recibió 2 votos a favor en más de 1 año. Por el contrario, el comentario que dice que debe usar funciones incorporadas obtuvo 58 votos a favor. O como dijo un comentarista:> Si todos estuviéramos limitados al mismo conjunto de funciones integradas, APL o Golfscript ganarían cada concurso porque sus nombres de comando son los más cortos. (Michael Stern)
Stephan Schinkel

1
o simplemente para decirlo de otra manera: ¿podemos usar printf? ¿o deberíamos usar asm en línea para activar la interrupción 21?
Stephan Schinkel

Un buen punto! No tenía la intención de molestar, ¡solo quería ser útil! ¡Entonces supongo que Mathematica podría ganar CreateUUID[]!
Dom Hastings

1
@StephanSchinkel "Solo 2 votos a favor en un año" es engañoso. Tiene 47 votos a favor y 45 votos a favor en este momento, por lo que un neto +2. Dicho esto, el umbral generalmente aceptado es más alto que eso, por lo que tienes razón en que "realmente" no cuenta como una laguna estándar en este momento.
Geobits

3

gawk, 86

BEGIN{for(srand();j++<32;printf(j~"^9|13|17|21"?"-":E)"%c",x+(x>10?87:48))x=rand()*16}

Puede usar esto una vez cada segundo para generar un "UUID" aleatorio único. Esto se debe a que srand()utiliza el tiempo del sistema en segundos desde epoch como argumento si no se proporciona ningún argumento.

for n in `seq 100` do awk 'BEGIN{for(srand();j++<32;printf(j~"^9|13|17|21"?"-":E)"%c",x+(x>10?87:48))x=rand()*16}'; sleep 1; done

Creo que la parte awk es bastante elegante.

BEGIN{
    srand()
    for(;j++<32;) {
        x=rand()*16
        x+=(x>10?87:48)
        printf "%c", x
        if(j~"^8|12|16|20")printf "-"
    }
}

Si desea usarlo más de una vez por segundo, puede llamarlo en bash de esta manera. Tenga en cuenta que la parte awk también cambia.

echo `awk 'BEGIN{for(srand('$RANDOM');j++<32;printf(j~"^9|13|17|21"?"-":E)"%c",x+(x>10?87:48))x=rand()*16}'`

Se echoagrega allí para imprimir una nueva línea cada vez.


3

K5, 35 bytes

"-"/(0,8+4*!4)_32?`c$(48+!10),65+!6

Para generar un alfabeto hexadecimal, genero una cadena de caracteres ( `c$) a partir de una lista de dígitos ( 48+!10) y las primeras 6 letras mayúsculas ( 65+!6). Una forma alternativa de generar los dígitos que tiene la misma longitud es,/$!10 .

Con la cadena "0123456789ABCDEF" generada, el resto es simple. Seleccione 32 valores aleatorios de este conjunto ( 32?), corte ( _) la cadena resultante en la 0 8 12 16 20vía calculada (0,8+4*!4)y luego una los fragmentos de cadena resultantes con guiones ("-"/ ).

En acción:

  "-"/(0,8+4*!4)_32?`c$(48+!10),65+!6
"9550E114-A8DA-9533-1B67-5E1857F355E1"

3

R , 63 bytes

x=sample(c(0:9,letters[1:6]),36,1);x[0:3*5+9]='-';cat(x,sep='')

Pruébalo en línea!

El código primero crea una cadena aleatoria de 36 caracteres y luego coloca los cuatro guiones. Produce un UUID a stdout.


Reemplace la cllamada sprintf("%x",0:15)por -1.
J.Doe

3

JavaScript, ES6, 106 bytes

"8-4-4-4-12".replace(/\d+/g, m => {t=0;for(i=0; i<m; i++) {t+=(Math.random()*16|0).toString(16)}return t})

Utiliza Regex reemplazar. Trata la cadena de formato como un recuento para generar un carácter hexadecimal. Levantando donde puedo; omitiendo punto y coma cuando sea posible.


89 bytes, '8-4-4-4-12'.replace(/\d+/g,n=>Math.floor(16**n*Math.random()).toString(16).padStart(n,0))
kamoroso94

2

Perl 6 , 53 bytes

El obvio:

say join '-',(0..9,'a'..'f').flat.roll(32).rotor(8,4,4,4,12)».join # 67

Al traducir el ejemplo de Perl 5 usando printf, se obtiene un código que es un poco más corto.

printf ($_='%04x')~"$_-"x 4~$_ x 3,(0..^4⁸).roll(8) # 53

(0..16⁴)?! ¿Puedes hacer eso en Perl?
aplaude el

1
@VoteToSpam Puede desde hace 9 días . (Perl 6 se lanzará a finales de este mes)
Brad Gilbert b2gills

Cooooool Tal vez debería aprenderlo
aplauso el

@VoteToSpam Eso no es nada en comparación con lo 1,2,4,8,16 ... *que genera una lista infinita perezosa de los poderes de 2. ( {2**$++} ... *también funciona)
Brad Gilbert b2gills

2

Kotlin , 175 bytes

fun main(a:Array<String>){
fun f()="0123456789abcdef".get((Math.random()*16).toInt())
var s=""
for(i in listOf(8,4,4,4,12)){
for(j in 1..i)
s+=f()
if(i!=12)s+="-"}
println(s)}

Pruébalo en línea!

Mi primer programa de Kotlin y presentación de PPCG


152 bytes -> tio.run/…
jrtapsell

2

APL (Dyalog Unicode) , 115 78 bytes

a←⊣,'-',⊢
H←⊃∘(⎕D,819⌶⎕A16∘⊥⍣¯1
(H 8?16)a(H 4?16)a(H 4?16)a(H 4?16)a H 12?16

Pruébalo en línea!

Esta es mi primera presentación APL. Muchas gracias a @ Adám por ayudarme en el chat APL de PPCG y por la función de conversión hexadecimal.

Gracias a @ Zacharý por 1 byte

Editado para arreglar el conteo de bytes.


Puede asumir ⎕IO←0sin costo alguno, Adám hace mucho. Además, la mayoría de los bytes (IIRC, todos los que tiene aquí) se pueden contar como uno en APL.
Zacharý

@ Zacharý He usado TIO para contar los bytes de mi envío, ¿debería haber usado el número de caracteres? Todavía soy nuevo en PPCG y uso APL, por lo que no tengo mucho conocimiento real de cómo hacer el conteo de bytes.
J. Sallé

Además, puede cambiar a(H 12?16)a a H 12?16para guardar un byte.
Zacharý


2

Japt , 32 bytes

[8,4,4,4,12]m@MqG**X sG ù0X} q"-

Pruébalo en línea!


Bienvenido a PPCG y bienvenido a Japt :) Revisaré sus soluciones hasta ahora cuando pueda hacer algo de tiempo (acabo de regresar de vacaciones, hay mucho para ponerse al día), pero el primer consejo que ofreceré es familiarizarme usted mismo con los accesos directos de Unicode ( m@- £, por ejemplo) y, para ayudarlo a comenzar, aquí hay una versión de 24 bytes de su solución: ethproductions.github.io/japt/… Acceda a la sala de chat de Japt si tiene alguna pregunta.
Shaggy

1

MATLAB / Octave, 95 bytes

a='-';b=strcat(dec2hex(randi(16,32,1)-1)');[b(1:8) a b(9:12) a b(13:16) a b(17:20) a b(21:32)]

1

Perl , 51 bytes

say"xx-x-x-x-xxx"=~s/x/sprintf"%04x",rand 65536/reg

Requiere perl5> = 5.10, creo. Para el modificador / r y para say ().


1
¡Agradable! ¡Eso es mucho mejor que el mío! Después de analizar su solución, incluso podría ahorrar más en función de esta meta publicación con el s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/eguso de -pflag, también significaría que funciona sin versiones anteriores -E.
Dom Hastings

Gracias. Su sugerencia es: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg 'Y eso es solo 48 caracteres entre' '. (¿Es este tipo de trampa? Quizás no)
Kjetil S.

Según esta meta publicación , es aceptable, todavía no he tenido la oportunidad de utilizar ese mecanismo, ¡pero espero que lo haga pronto! Sería 49 bytes (+ -p) pero aún así bastante bueno y no hubiera considerado ese enfoque sin ver su respuesta.
Dom Hastings


1

C ++, 194 193 221 210 201 bytes

+7 bytes gracias a Zacharý (detectado un -que no debería estar al final)

#include<iostream>
#include<random>
#include<ctime>
#define L(a)for(int i=0;i<a;++i)std::cout<<"0123456789abcdef"[rand()%16];
#define P(a)printf("-");L(a)
void t(){srand(time(0));L(8)P(4)P(4)P(4)P(12)}

Si alguien tiene una manera de obtener un valor diferente en cada ejecución sin cambiar srandy sin incluir <ctime>, sería genial


No puede #define L(a) for... ser #define L(a)for...? (Podría haber preguntado eso)
Zacharý

Esto no es válido, hay un "-" al final (que no debería haber)
Zacharý

Corrección @ Zacharý aplicada ahora
HatsuPointerKun


1
¿Podría hacer algo como "0123456789abcdef"[rand()%16], y luego eliminar f?
Zacharý

1

Befunge-93 , 97 bytes

v>4448v,+<    <
0*    :  >59*0^
62v0-1_$:|>*6+^
>^>41v < @^99<
v<*2\_$:54+` |
?0>+\1-^ v*68<>
>1^

Pruébalo en línea!

Estoy seguro de que esto puede reducirse, pero este es mi primer intento :)


1

Bash, 67 bytes

for l in 4 2 2 2 6;{ o+=`xxd -p -l$l</dev/random`-;}
echo ${o::-1}

Bienvenido a PPCG!
Dennis

1

JavaScript REPL, 79 bytes

'66-6-6-6-666'.replace(/6/g,_=>(Math.random().toString(16)+'00000').slice(2,6))

Pruébalo en línea!

Math.randompuede devolver 0. Agregar 5 ceros hace que el corte sea de 4 0s


1

Adelante (adelante) , 91 89 bytes

include random.fs
hex
: f 0 4 4 4 8 20 0 do dup i = if + ." -" then 10 random 1 .r loop ;

Pruébalo en línea!

Explicación

Cambia la base a hexadecimal, luego genera números / segmentos de la longitud apropiada con guiones a intervalos específicos

Explicación del código

include random.fs          \ include the random module
hex                        \ set the base to hexadecimal
: f                        \ start a new word definition
  0 4 4 4 8                \ enter the intervals to place dashes
  20 0 do                  \ start a counted loop from 0 to 0x20 (32 in decimal)
    dup i =                \ check if we are on a character that needs a dash
    if                     \ if we are
      +                    \ calculate the next character that gets a dash
      ." -"                \ output a dash
    then                   \ end the if block
    f random               \ get a random number between 0x0 and 0xf
    1 .r                   \ output it right-aligned in 1-character space
  loop                     \ end the loop
;                          \ end the word definition

1

C (gcc) ,  94   91  86 bytes

main(i){srand(&i);i=803912;for(;i--%16||(i/=16)&&printf("-");printf("%x",rand()%16));}

Pruébalo en línea!

Me hubiera gustado sugerir esta versión en un comentario a Max Yekhlakov ( su respuesta ), pero desafortunadamente todavía no tengo los 50 puntos de reputación necesarios, así que aquí está mi respuesta.

803912está C4448en hexadecimal, describe cómo se debe formatear la salida ( 12-4-4-4-8), se invierte porque los dígitos menos significativos se leerán primero.
 

Ediciones:

  • ahorró 3 bytes gracias a Jonathan Frech
  • ahorró 5 bytes más al reemplazar srand(time(0))consrand(&i)

1
main(){...;int i=puede ser main(i){...;i=.
Jonathan Frech

He estado pensando en algo, aparentemente srand()acepto un unsigned intcomo su parámetro semilla. En tio.run, an unsigned inttiene 4 bytes de longitud pero el UUID tiene 16 bytes de longitud. Esto significa que solo se generará una pequeña fracción de las salidas válidas (1/2 ^ 12), por lo que mi solución (así como la anterior con time(0)) no es válida. Qué piensas ?
Annyo

El OP dice Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. La entropía inicial no necesariamente determina la entropía RNG, aunque probablemente sí (no verificó la srand()implementación). Sin embargo, srand()que yo sepa , es razonablemente uniforme, por lo que si el RNG fuera perfecto, aún sería uniforme. Por lo tanto, creo que su respuesta es válida.
Jonathan Frech

Vale, entiendo. También podría enviar mi respuesta como una función, suponiendo que srand()ya se haya hecho, y en este caso no habrá dudas. Pero no estoy seguro de si esto está permitido, otras presentaciones C / C ++ parecen incluir srand()int la respuesta (a menos que no se use rand())
Annyo


1

C (gcc), 143 110 103 96 94 bytes

Golfed hasta 94 bytes gracias a ceilingcat y Jonathan Frech.

(*P)()="\xf\x31À";*z=L"\10\4\4\4\14";main(n){for(;*z;*++z&amp;&amp;putchar(45))for(n=*z;n--;printf("%x",P()&amp;15));}

Pruébalo en línea!

Explicación:

/*
  P is a pointer to a function.
  The string literal contains actual machine code of the function:

  0F 31     rdtsc
  C3        ret

  0xc3 is the first byte of the UTF-8 representation of the character À
*/
(*P)() = "\xf\61À";

// encode uuid chunk lengths as literal characters
// we use wide characters with 'L' prefix because
// sizeof(wchar_t)==sizeof(int) for 64-bit gcc C on TIO
// so z is actually a zero-terminated string of ints
*z = L"\8\4\4\4\14"

main (n)
{
    for (
        ; 

        // loop until we reach the trailing zero
        *z;

        // increase the pointer and dereference it
        *++z 
             // and output a hyphen, if the pointer does not point at zero
             && putchar(45) 
    )
        // output a random hex string with length pointed at by z
        for (n = *z; n--; printf ("%x", P()&15));
}

1
Hola y bienvenidos a PPCG! 110 bytes .
Jonathan Frech

@ JonathanFrech ¡Gracias! ¡Tu versión es muy impresionante!
Max Yekhlakov

Sugerir en *z=L"\27\23\17\vz"lugar de *z=L"\10\4\4\4\14"y en for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)lugar defor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

Java con Ten Foot Laser Pole v. 1.06, 126 bytes

String u(){return sj224.tflp.util.StringUtil.replace("aa-a-a-a-aaa","a",s->String.format("%04x",(int)(Math.random()*65536)));}

Probado con la versión 1.06 de la biblioteca, pero esto debería funcionar con cualquier versión 1.04 o posterior.



0

SmileBASIC, 65 62 bytes

DEF G H?"-";:END
DEF H?HEX$(RND(65536),4);
END H G G G G H H H

He creado una función para imprimir 4 dígitos hexadecimales aleatorios: DEF H?HEX$(RND(65536),4);:ENDasí como 4 dígitos con una -después de ellos DEF G:H?"-";:END. Entonces solo tiene que llamar a estas funciones muchas veces.


0

Chip , 109 + 6 = 115 bytes

Requiere banderas -wc36, causando +6 bytes

!ZZZZZZZZZZZZZZZZZZZZZZ
,-----.,+vv--^----^---z
?]]]--R\acd
?xx+-)\\b
?x+x-)\\c
?^xx\--\d
`-xx]v~\e
f*`)'`-\g

Pruébalo en línea!

Genera 4 bits aleatorios (los cuatro ?) y los convierte en dígitos hexadecimales:

  • 0x0- 0x9=> 0-9
  • 0xa- 0xe=> b-f
  • 0xf => a

... un poco poco convencional, pero me ahorró algunos bytes sin costo para la distribución de resultados.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.