Générer un UUID aléatoire


15

J'ai besoin d'un UUID. Votre travail consiste à en générer un.

L'UUID canonique (Universally Unique IDentifier) ​​est un nombre hexadécimal à 32 chiffres avec des tirets insérés à certains points.Le programme devrait produire 32 chiffres hexadécimaux (128 bits), sous la forme de xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12chiffres), où xest un nombre hexadécimal aléatoire. En supposant que le PRNG de votre langue est parfait, toutes les sorties valides doivent avoir la même probabilité d'être générées.

TL; DR

Générez 32 chiffres hexadécimaux aléatoires dans les 8-4-4-4-12chiffres du formulaire . Le code le plus court gagne.

EDIT: Doit être hexadécimal. Toujours générer uniquement des décimales n'est pas valide. EDIT 2: Aucun intégré. Ce ne sont pas des GUID, juste des chiffres hexadécimaux génériques.


Exemple de sortie:

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

L'entrée et les failles standard sont interdites.


C'est le , donc le code le plus court l'emporte. N'hésitez pas non plus à demander des clarifications.


5
On dirait une version moins stricte de codegolf.stackexchange.com/q/32309/14215
Geobits

9
"Ces exemples ne sont pas aléatoires. Essayez d'attacher une certaine signification." Qu'est-ce que ça veut dire?
Alex A.

3
En fait, on n'a pas besoin de nombres hexadécimaux, 10 bases peuvent également être aléatoires. Par exemple, 12345678-1234-1234-1234-123456789012devrait être un UUID valide (ou un chiffre hexadécimal est-il nécessaire?). Considérez-vous cela comme une échappatoire?
Voitcus

3
Le titre et la première phrase suggèrent que vous voulez un UUID canonique, et les exemples donnés semblent suivre la spécification des UUID, mais vous semblez en fait demander autre chose.
Peter Taylor

3
Je me sens obligé de souligner que la version 4 (aléatoire) de l'UUID a un format requis d' xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxyest l'un [89AB]. Au moment de ce commentaire, aucune des réponses (à l'exception de C # utilisant une bibliothèque intégrée) n'est garantie de produire un UUID aléatoire valide (et en fait, il est fort probable qu'il n'en produise pas).

Réponses:


11

Pyth, 20 octets

j\-msm.HO16*4hdj83 3

Manifestation.

Encode [1, 0, 0, 0, 2]83 en base 3, puis en ajoute un et multiplie par quatre pour obtenir la longueur de chaque segment. Fait ensuite des chiffres hexadécimaux et joint les traits d'union.


8

Julia, 80 octets

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

Générez un entier aléatoire de 128 bits, obtenez sa représentation hexidécimale sous la forme d'une chaîne complétée à 32 chiffres et divisez-la en segments joints avec des tirets.

Merci à ConfusedMr_C et kvill pour leur aide!


8

CJam, 26 25 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

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 octets

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

modifier: parens étrangers:

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

edit: a pu supprimer le .Trim ("-") de fin de l'original:

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

Cela peut être plus clair avec certains espaces étant donné la nature des drapeaux (-f et -Join). J'aimerais toujours perdre le Trim final ("-"):

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

Ou, en utilisant la fonctionnalité intégrée (ala la réponse C # ci-dessus)

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

Cependant, il semble un petit raccourci-y même s'il arrive à 31 octets.


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

5

Python 2, 86 84 octets

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

Cela enchaîne les formateurs de chaînes pour que Python formate les nombres hexadécimaux uniquement pour chaque segment.

Non 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

Cela pourrait nécessiter quelques améliorations, mais je suis fier.



4

PHP, 69 72 75 octets

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

Cela ne produit pas de chiffres hexadécimaux ( a, ... f). Ils sont autorisés, mais pas requis par le corps de la question.

Aucun groupe de chiffres ne commence par 0 (également non requis).

edit: sauvé 3 octets grâce à @IsmaelMiguel


Cela ressemble à un bi de plus de 32 octets.
isaacg du

@isaacg oui, désolé - mon erreur
Voitcus

Vous devez utiliser à la join()place.
Ismael Miguel du

3

C #, 65 octets

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

modifier: Oui! C # est plus court qu'un autre langage (à part Java) :)


1
Je pense que cela est considéré comme une échappatoire standard ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings

1
Je pense que ce n'est pas considéré comme une échappatoire standard: comme vous pouvez le voir, la demande d'abandon de ce truc vient de recevoir 2 votes positifs en plus d'un an. À l'inverse, le commentaire qui dit que vous devez utiliser les fonctions intégrées a obtenu 58 votes positifs. Ou comme l'a dit un commentateur -> Si nous étions tous limités au même ensemble de fonctions intégrées, chaque concours serait gagné par APL ou Golfscript car leurs noms de commande sont les plus courts. (Michael Stern)
Stephan Schinkel

1
ou pour le dire autrement: pouvons-nous utiliser printf? ou devrions-nous utiliser asm en ligne pour déclencher l'interruption 21?
Stephan Schinkel

Un bon point! Je n'avais pas l'intention de bouleverser, je voulais seulement être utile! Je suppose que Mathematica pourrait gagner avec CreateUUID[]!
Dom Hastings du

1
@StephanSchinkel Les "seulement 2 votes positifs par an" sont trompeurs. Il a 47 votes positifs et 45 votes négatifs en ce moment, donc un net +2. Cela étant dit, le seuil généralement accepté est plus élevé que cela, donc vous avez raison de dire qu'il ne compte pas "vraiment" comme une échappatoire standard en ce moment.
Geobits du

3

gawk, 86

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

Vous pouvez l'utiliser une fois par seconde pour générer un "UUID" aléatoire unique. En effet, srand()utilise le temps système en secondes depuis epoch comme argument s'il n'y a pas d'argument donné.

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

Je pense que la partie awk est plutôt élégante.

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

Si vous souhaitez l'utiliser plus d'une fois par seconde, vous pouvez l'appeler en bash comme ceci. Notez que la partie awk est également modifiée.

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

Le echoest ajouté pour imprimer une nouvelle ligne à chaque fois.


3

K5, 35 octets

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

Pour générer un alphabet hexadécimal, je génère une chaîne de caractères ( `c$) à partir d'une liste de chiffres ( 48+!10) et des 6 premières lettres majuscules (65+!6 ). Une autre manière de générer des chiffres de même longueur est,/$!10 .

Avec la chaîne "0123456789ABCDEF" générée, le reste est simple. Sélectionnez 32 valeurs aléatoires dans cet ensemble ( 32?), coupez ( _) la chaîne résultante à0 8 12 16 20 calculée via(0,8+4*!4) , puis joignez les fragments de chaîne résultants avec des tirets ( "-"/).

En action:

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

3

R , 63 octets

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

Essayez-le en ligne!

Le code crée d'abord une chaîne aléatoire de 36 caractères, puis place les quatre tirets. Il envoie un UUID à stdout.


Remplacez l' cappel par sprintf("%x",0:15)-1.
J.Doe

3

JavaScript, ES6, 106 octets

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

Utilise Regex remplacer. Traite la chaîne de format comme un décompte pour générer un caractère hexadécimal. Hisser partout où je peux; en omettant les points-virgules si possible.


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

L'évident:

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

La traduction de l'exemple Perl 5 en utilisant un printfcode un peu plus court.

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

(0..16⁴)?! Vous pouvez faire ça en Perl?
clap

1
@VoteToSpam Vous pouvez depuis 9 jours . (Perl 6 sortira plus tard ce mois-ci)
Brad Gilbert b2gills

Cooooool. Peut-être que je devrais l'apprendre
clap

@VoteToSpam Ce n'est rien comparé à 1,2,4,8,16 ... *ce qui génère une liste infinie paresseuse des puissances de 2. ( {2**$++} ... *fonctionne également)
Brad Gilbert b2gills

2

Kotlin , 175 octets

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

Essayez-le en ligne!

Mon tout premier programme Kotlin et soumission PPCG


152 octets -> tio.run/…
jrtapsell

2

APL (Dyalog Unicode) , 115 78 octets

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

Essayez-le en ligne!

Ceci est ma première soumission APL. Un grand merci à @ Adám pour m'avoir accompagné lors du chat APL du PPCG et pour la fonction de conversion hexadécimale.

Merci à @ Zacharý pour 1 octet

Modifié pour corriger le nombre d'octets.


Vous pouvez supposer ⎕IO←0sans frais d'octet, Adám fait beaucoup. De plus, la plupart des octets (IIRC, tous ceux que vous avez ici) peuvent être comptés comme un dans APL.
Zacharý

@ Zacharý J'ai utilisé TIO pour compter les octets pour ma soumission, aurais-je dû utiliser le nombre de caractères à la place? Je suis encore nouveau sur PPCG et j'utilise APL, donc je n'ai pas vraiment de connaissances réelles sur la façon de compter les octets pour cela.
J.Sallé

En outre, vous pouvez changer a(H 12?16)pour a H 12?16sauver un octet.
Zacharý


2

Japt , 32 octets

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

Essayez-le en ligne!


Bienvenue à PPCG et bienvenue à Japt :) Je vais parcourir vos solutions jusqu'à présent quand je pourrai prendre du temps (juste de retour de vacances, tant de choses à rattraper), mais le premier conseil que je vous proposerai est de vous familiariser vous-même avec les raccourcis Unicode ( m@- £, par exemple) et, pour vous aider à démarrer, voici une version de 24 octets de votre solution golfée à la hâte : ethproductions.github.io/japt/… Placez -vous dans le salon de discussion Japt si vous avez des questions.
Shaggy

1

MATLAB / Octave, 95 octets

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 octets

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

Nécessite perl5> = 5.10 je pense. Pour le modificateur / r et pour say ().


1
Agréable! C'est bien mieux que le mien! Après avoir examiné votre solution, vous pourriez même être en mesure d'économiser davantage sur la base de cette méta-publication avec l' s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/egutilisation de l' -pindicateur, cela signifierait également qu'elle fonctionne sur les anciennes versions sans -E.
Dom Hastings

Merci. Votre suggestion est: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg 'Et c'est juste 48 caractères entre' '. (Est-ce que ce genre de tricherie? Peut-être pas)
Kjetil S.

Selon ce meta post, c'est acceptable, je n'ai pas encore eu l'occasion d'utiliser ce mécanisme moi-même, mais j'espère que je le ferai bientôt! Serait de 49 octets (+ -p) mais toujours assez bon et je n'aurais pas envisagé cette approche sans voir votre réponse!
Dom Hastings


1

C ++, 194 193 222 210 210 201 octets

+7 octets grâce à Zacharý (détecté un -qui ne devrait pas être à la fin)

#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 quelqu'un a un moyen d'obtenir une valeur différente à chaque exécution sans changer srandet sans inclure <ctime>, ce serait bien


Ne peut pas #define L(a) for... être #define L(a)for...? (Pourrait avoir déjà demandé cela)
Zacharý

Ceci n'est pas valide, il y a un "-" à la fin (ce qui ne devrait pas être le cas)
Zacharý

@ Zacharý Correction appliquée maintenant
HatsuPointerKun


1
Pourriez-vous faire quelque chose comme "0123456789abcdef"[rand()%16], puis supprimer f?
Zacharý

1

Befunge-93 , 97 octets

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

Essayez-le en ligne!

Je suis sûr que cela peut être réduit, mais c'est mon premier essai :)


1

Bash, 67 octets

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

Bienvenue chez PPCG!
Dennis

1

JavaScript REPL, 79 octets

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

Essayez-le en ligne!

Math.randompeut revenir 0. L'ajout de 5 zéros permet au découpage d'obtenir 4 0s


1

Forth (gforth) , 91 89 octets

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

Essayez-le en ligne!

Explication

Change la base en hexadécimal, puis sort des nombres / segments de la longueur appropriée avec des tirets à intervalles spécifiés

Explication du code

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 octets

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

Essayez-le en ligne!

J'aurais aimé proposer cette version dans un commentaire à Max Yekhlakov ( sa réponse ), mais malheureusement je n'ai pas encore les 50 points de réputation nécessaires, alors voici ma réponse.

803912est C4448en hexadécimal, il décrit comment la sortie doit être formatée ( 12-4-4-4-8), elle est inversée car les chiffres les moins significatifs seront lus en premier.
 

Modifications:

  • économisé 3 octets grâce à Jonathan Frech
  • enregistré 5 octets de plus en remplaçant srand(time(0))parsrand(&i)

1
main(){...;int i=peut être main(i){...;i=.
Jonathan Frech

J'ai pensé à quelque chose, srand()j'accepte apparemment un unsigned intcomme paramètre de départ. Sur tio.run, an unsigned intfait 4 octets mais l'UUID fait 16 octets. Cela signifie que seule une infime fraction des sorties valides (1/2 ^ 12) sera générée, donc ma solution (ainsi que la précédente avec time(0)) n'est pas valide. Qu'est-ce que tu penses ?
Annyo

Le PO indique Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. L'entropie de la graine ne détermine pas nécessairement l'entropie du RNG, bien qu'elle le fasse probablement (n'a pas vérifié la srand()mise en œuvre). Cependant, srand()est à ma connaissance raisonnablement uniforme, donc si le RNG était parfait, il serait toujours uniforme. Je pense donc que votre réponse est valable.
Jonathan Frech

OK, je comprends. Je pourrais également soumettre ma réponse en tant que fonction, en supposant que cela srand()a déjà été fait, et dans ce cas il n'y aura aucun doute. Mais je ne sais pas si cela est autorisé, d'autres soumissions C / C ++ semblent toutes inclure srand()la réponse (à moins qu'elle n'utilise pas rand())
Annyo


1

C (gcc), 143 110 103 96 94 octets

Golfé à 94 octets grâce à plafondcat et 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));}

Essayez-le en ligne!

Explication:

/*
  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
Bonjour et bienvenue chez PPCG! 110 octets .
Jonathan Frech

@JonathanFrech Merci! Votre version est très impressionnante!
Max Yekhlakov

Suggérer à la *z=L"\27\23\17\vz"place de *z=L"\10\4\4\4\14"et for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)au lieu defor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
plafondcat

1

Java avec Ten Foot Laser Pole v. 1.06, 126 octets

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

Testé avec la version 1.06 de la bibliothèque, mais cela devrait fonctionner avec n'importe quelle version 1.04 ou plus récente.



0

SmileBASIC, 65 62 octets

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

J'ai créé une fonction pour imprimer 4 chiffres hexadécimaux aléatoires: DEF H?HEX$(RND(65536),4);:ENDainsi que 4 chiffres avec un -après eux DEF G:H?"-";:END. Ensuite, il suffit d'appeler ces fonctions plusieurs fois.


0

Puce , 109 + 6 = 115 octets

Nécessite des drapeaux -wc36, provoquant +6 octets

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

Essayez-le en ligne!

Génère 4 bits aléatoires (les quatre ?) et convertit en chiffres hexadécimaux:

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

... un peu non conventionnel, mais cela m'a fait économiser quelques octets sans frais pour la distribution des résultats.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.