Genera UUID casuale


15

Ho bisogno di un UUID. Il tuo compito è di generarne uno.

L'UUID canonico (Universally Unique IDentifier) ​​è un numero esadecimale di 32 cifre con trattini inseriti in alcuni punti. Il programma dovrebbe generare 32 cifre esadecimali (128 bit), sotto forma di xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12cifre), dove xè un numero esadecimale casuale. Supponendo che il PRNG della tua lingua sia perfetto, tutti gli output validi devono avere la stessa probabilità di essere generati.

TL; DR

Genera 32 cifre esadecimali casuali nelle cifre del modulo 8-4-4-4-12. Il codice più corto vince.

EDIT: deve essere esadecimale. Generare sempre solo decimale non è valido. EDIT 2: nessun built-in. Questi non sono GUID, solo cifre esadecimali generiche.


Esempio di output:

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

Non sono consentite immissioni e scappatoie standard .


Questo è , quindi vince il codice più corto. Inoltre, non esitare a chiedere chiarimenti.


5
Sembra una versione meno rigorosa di codegolf.stackexchange.com/q/32309/14215
Geobits

9
"Questi esempi non sono casuali. Cerca di dare un significato." Cosa significa?
Alex A.

3
In realtà, uno non ha bisogno di numeri esadecimali, 10 base può anche essere casuale. Ad esempio, 12345678-1234-1234-1234-123456789012dovrebbe essere un UUID valido (o è necessaria una cifra esadecimale?). Consideri questa una scappatoia?
Voitcus,

3
Il titolo e la prima frase suggeriscono che si desidera un UUID canonico e gli esempi forniti sembrano seguire le specifiche degli UUID, ma in realtà sembra che si stia chiedendo qualcos'altro.
Peter Taylor,

3
Mi sento in dovere di sottolineare che l'UUID versione 4 (casuale) ha un formato richiesto di xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx dove si ytrova [89AB]. Al momento di questo commento, nessuna delle risposte (tranne C # che utilizza una libreria integrata) è garantita per produrre un UUID casuale valido (e in realtà, è molto probabile che non ne produca uno).

Risposte:


11

Pyth, 20 byte

j\-msm.HO16*4hdj83 3

Dimostrazione.

Codifica [1, 0, 0, 0, 2]come 83 in base 3, quindi ne aggiunge uno e si moltiplica per quattro per ottenere la lunghezza di ciascun segmento. Quindi crea cifre esadecimali e unisce i trattini.


8

Julia, 80 byte

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

Genera un numero intero a 128 bit casuale, ottieni la sua rappresentazione esadecimale come una stringa riempita con 32 cifre e dividila in segmenti uniti con trattini.

Grazie a ConfusedMr_C e kvill per il loro aiuto!


8

CJam, 26 25 byte

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

Provalo online nell'interprete CJam .

Come funziona

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 byte

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

modifica: parentesi estranee:

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

modifica: è stato in grado di rimuovere il .Trim finale ("-") dall'originale:

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

Potrebbe essere più chiaro con alcuni spazi bianchi data la natura dei flag (-f e -Join). Vorrei ancora perdere il Trim finale ("-"):

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

Oppure, utilizzando la funzionalità integrata (ala sopra la risposta C # sopra)

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

Tuttavia, sembra un po 'scorciatoia-y anche se arriva a 31 byte.


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

5

Python 2, 86 84 byte

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

Questa catena formatta stringhe per rendere Python formattare i numeri esadecimali in modo univoco per ciascun segmento.

Ungolfed:

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

Ciò potrebbe comportare alcuni miglioramenti, ma sono orgoglioso.



4

PHP, 69 72 75 byte

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

Questo non genera cifre esadecimali ( a, ... f). Sono consentiti, ma non richiesti dall'organismo di domanda.

Nessun gruppo di cifre inizia con 0(anche non richiesto).

modifica: salvato 3 byte grazie a @IsmaelMiguel


Sembra un bi più di 32 byte.
isaacg,

@isaacg sì, scusa - errore mio
Voitcus,

Dovresti usare join()invece.
Ismael Miguel,

3

C #, 65 byte

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

modifica: Sì! C # è più breve di un'altra lingua (oltre a Java) :)


1
Penso che questa sia considerata una scappatoia standard ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings,

1
Penso che questo non sia considerato una scappatoia standard: come puoi vedere la richiesta di abbandonare questa roba ha appena ottenuto 2 voti in oltre 1 anno. Al contrario, il commento che dice che dovresti usare le funzioni integrate ha ottenuto 58 voti positivi. O come ha detto un commentatore -> Se fossimo tutti limitati allo stesso set di funzioni integrate, ogni concorso sarebbe vinto da APL o Golfscript perché i loro nomi di comando sono i più brevi. (Michael Stern)
Stephan Schinkel,

1
o per dirla in altro modo: possiamo usare printf? o dovremmo usare inline asm per innescare l'interrupt 21?
Stephan Schinkel,

Un buon punto! Non avevo intenzione di arrabbiarmi, intendevo solo essere d'aiuto! Immagino quindi che Mathematica potrebbe vincere CreateUUID[]!
Dom Hastings,

1
@StephanSchinkel I "soli 2 voti in un anno" sono fuorvianti. Al momento ha 47 voti positivi e 45 voti negativi, quindi un netto +2. Detto questo, la soglia generalmente accettata è più alta di così, quindi hai ragione che in questo momento non "conta" come una scappatoia standard.
Geobits,

3

stupido, 86

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

Puoi usarlo una volta al secondo per generare un "UUID" casuale univoco. Questo perché srand()utilizza il tempo di sistema in secondi dall'epoca come argomento se non viene fornito alcun argomento.

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

Penso che la parte awk sia piuttosto elegante.

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

Se vuoi usarlo più spesso di una volta al secondo, puoi chiamarlo in bash in questo modo. Si noti che anche la parte awk è cambiata.

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

La echosi aggiunge lì per stampare una nuova linea ogni volta.


3

K5, 35 byte

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

Per generare un alfabeto esadecimale, creo una stringa di caratteri ( `c$) da un elenco di cifre ( 48+!10) e le prime 6 lettere maiuscole ( 65+!6). Un modo alternativo di generare le cifre della stessa lunghezza è ,/$!10.

Con la stringa "0123456789ABCDEF" generata, il resto è semplice. Seleziona 32 valori casuali da questo set (32? ), tagliare ( _) la stringa risultante al 0 8 12 16 20calcolo via (0,8+4*!4), quindi unire i frammenti di stringa risultanti con trattini ( "-"/).

In azione:

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

3

R , 63 byte

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

Provalo online!

Il codice crea prima una stringa casuale di 36 caratteri, quindi posiziona i quattro trattini. Emette un UUID su stdout.


Sostituisci la cchiamata con sprintf("%x",0:15)per -1.
J.Doe,

3

JavaScript, ES6, 106 byte

"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})

Utilizza Regex sostituisci. Considera la stringa di formato come un conteggio per la generazione di un carattere esadecimale. Sollevare dove posso; omettendo i punti e virgola ove possibile.


89 byte,'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 byte

Quello ovvio:

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

Traducendo l'esempio di Perl 5 usando printf, si ottiene un codice un po 'più breve.

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

(0..16⁴)?! Puoi farlo in Perl?
applaude il

1
@VoteToSpam Puoi farlo fino a 9 giorni fa . (Perl 6 uscirà alla fine di questo mese)
Brad Gilbert b2gills il

Cooooool. Forse dovrei impararlo
applausi il

@VoteToSpam Non è niente rispetto a quello 1,2,4,8,16 ... *che genera un pigro infinito elenco dei poteri di 2. ( {2**$++} ... *funziona anche)
Brad Gilbert b2gills

2

Kotlin , 175 byte

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)}

Provalo online!

Il mio primo programma Kotlin e presentazione PPCG


152 byte -> tio.run/…
jrtapsell

2

APL (Dyalog Unicode) , 115 78 byte

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

Provalo online!

Questa è la mia prima presentazione APL. Grazie mille a @ Adám per avermi accompagnato nella chat APL del PPCG e per la funzione di conversione esadecimale.

Grazie a @ Zacharý per 1 byte

Modificato per correggere il conteggio dei byte.


Puoi assumere ⎕IO←0senza costi byte, Adám lo fa molto. Inoltre, la maggior parte dei byte (IIRC, tutti quelli presenti qui) possono essere conteggiati come uno in APL.
Zacharý,

@ Zacharý Ho usato TIO per contare i byte per il mio invio, avrei dovuto usare invece il numero di caratteri? Sono ancora nuovo su PPCG e utilizzo APL, quindi non ho molta conoscenza effettiva di come fare il conteggio dei byte per esso.
J. Sallé,

Inoltre, è possibile passare a(H 12?16)a a H 12?16per salvare un byte.
Zacharý,


2

Japt , 32 byte

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

Provalo online!


Benvenuti in PPCG e benvenuti in Japt :) Prenderò in rassegna le vostre soluzioni finora quando potrò guadagnare un po 'di tempo (sono appena tornato dalle vacanze, così tanto da recuperare) ma il primo consiglio che offrirò è di familiarizzare te stesso con le scorciatoie Unicode ( m@- £, per esempio) e, per aiutarti ad iniziare, ecco una versione a 24 byte di fretta golfed della soluzione: ethproductions.github.io/japt/... goccia nella chatroom Japt se hai domande.
Shaggy,

1

MATLAB / Octave, 95 byte

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 byte

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

Richiede perl5> = 5.10 Penso. Per il modificatore / r e per dire ().


1
Bello! È molto meglio del mio! Dopo aver esaminato la tua soluzione, potresti anche essere in grado di risparmiare di più in base a questo meta post con l' s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/egutilizzo di -pflag, significherebbe anche che funziona su versioni precedenti senza -E.
Dom Hastings,

Grazie. Il tuo suggerimento è: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg 'E questo è solo 48 caratteri tra' '. (È questo tipo di imbroglio? Forse no)
Kjetil S.

Secondo questo meta post è accettabile, non ho ancora avuto l'opportunità di utilizzare quel meccanismo, ma spero di poterlo fare presto! Sarebbe 49 byte (+ -p) ma comunque abbastanza buono e non avrei considerato quell'approccio senza vedere la tua risposta!
Dom Hastings,


1

C ++, 194 193 221 210 201 byte

+7 byte grazie a Zacharý (rilevato un -che non dovrebbe essere alla fine)

#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)}

Se qualcuno ha un modo per ottenere un valore diverso ogni esecuzione senza cambiare srande senza includere <ctime>, sarebbe fantastico


Non puoi #define L(a) for... essere #define L(a)for...? (Potrebbe averlo già chiesto)
Zacharý,

Questo non è valido, c'è un "-" alla fine (che non dovrebbe esserci)
Zacharý

@ Correzione Zacharý ora applicata
HatsuPointerKun


1
Potresti fare qualcosa di simile "0123456789abcdef"[rand()%16]e poi rimuovere f?
Zacharý,

1

Befunge-93 , 97 byte

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

Provalo online!

Sono sicuro che questo può essere ridotto, ma questo è il mio primo tentativo :)


1

Bash, 67 byte

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

Benvenuti in PPCG!
Dennis,

1

REPL JavaScript, 79 byte

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

Provalo online!

Math.randompotrebbe tornare 0. L'aggiunta di 5 zeri fa sì che l'affettamento ottenga 4 0s


1

Forth (gforth) , 91 89 byte

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

Provalo online!

Spiegazione

Cambia la base in esadecimale, quindi genera numeri / segmenti della lunghezza appropriata con trattini a intervalli specificati

Spiegazione del codice

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 byte

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

Provalo online!

Mi sarebbe piaciuto suggerire questa versione in un commento a Max Yekhlakov (la sua risposta ), ma sfortunatamente non ho ancora i 50 punti reputazione necessari, quindi ecco la mia risposta.

803912è C4448in formato esadecimale, descrive come deve essere formattato l'output (12-4-4-4-8 ), è invertito perché verranno lette prima le cifre meno significative.
 

modifiche:

  • salvato 3 byte grazie a Jonathan Frech
  • salvato altri 5 byte sostituendoli srand(time(0))consrand(&i)

1
main(){...;int i=può essere main(i){...;i=.
Jonathan Frech,

Ho pensato a qualcosa, apparentemente ho srand()accettato un unsigned intcome parametro seed. Su tio.run, an unsigned intè lungo 4 byte ma l'UUID è lungo 16 byte. Ciò significa che verrà generata solo una piccola parte delle uscite valide (1/2 ^ 12), quindi la mia soluzione (così come la precedente con time(0)) non è valida. Cosa pensi ?
Annyo,

Il PO dichiara Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. L'entropia seme non determina necessariamente l'entropia RNG, anche se probabilmente (non ha verificato l' srand()implementazione). Tuttavia, srand()per quanto ne sappia , è ragionevolmente uniforme, quindi se l'RNG fosse perfetto, sarebbe comunque uniforme. Penso quindi che la tua risposta sia valida.
Jonathan Frech,

Ok ho capito. Potrei anche inviare la mia risposta come funzione, supponendo che srand()sia già stato fatto, e in questo caso non ci saranno dubbi. Ma non sono sicuro che ciò sia consentito, altri invii in C / C ++ sembrano tutti includere srand()nella risposta (a meno che non li usi rand())
Annyo


1

C (cc), 143 110 103 96 94 byte

Golfato fino a 94 byte grazie a ceilingcat e 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));}

Provalo online!

Spiegazione:

/*
  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
Ciao e benvenuto in PPCG! 110 byte .
Jonathan Frech,

@JonathanFrech Grazie! La tua versione è davvero impressionante!
Max Yekhlakov,

Suggerisci *z=L"\27\23\17\vz"invece di *z=L"\10\4\4\4\14"e for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)invece difor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

Java con palo laser a dieci piedi v. 1,06, 126 byte

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

Testato con la versione 1.06 della libreria, ma dovrebbe funzionare con qualsiasi versione 1.04 o successiva.



0

SmileBASIC, 65 62 byte

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

Ho creato una funzione per stampare 4 cifre esadecimali casuali: DEF H?HEX$(RND(65536),4);:ENDoltre a 4 cifre con un -dopo di loro: DEF G:H?"-";:END. Quindi deve solo chiamare queste funzioni un sacco di volte.


0

Patata fritta , 109 + 6 = 115 byte

Richiede bandiere -wc36 , causando +6 byte

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

Provalo online!

Genera 4 bit casuali (i quattro ? ) e li converte in cifre esadecimali:

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

... un po 'non convenzionale, ma mi ha salvato alcuni byte senza spese per la distribuzione dei risultati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.