Buat UUID acak


15

Saya membutuhkan UUID. Tugas Anda adalah menghasilkan satu.

UUID kanonik (Universally Unique IDentifier) ​​adalah angka heksadesimal 32 digit dengan tanda hubung dimasukkan dalam titik-titik tertentu. Program harus menghasilkan 32 digit hex (128 bit), dalam bentuk xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12digit), di mana xadalah angka heksadesimal acak. Dengan asumsi PRNG bahasa Anda sempurna, semua output yang valid harus memiliki probabilitas yang sama untuk dihasilkan.

TL; DR

Hasilkan 32 digit heksadesimal acak dalam bentuk 8-4-4-4-12digit. Kode terpendek menang.

EDIT: Harus heksadesimal. Selalu menghasilkan desimal saja tidak valid. EDIT 2: Tidak ada built-in. Ini bukan GUID, hanya digit hex umum.


Contoh 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

Input, dan celah standar tidak diizinkan.


Ini , jadi kode terpendek menang. Juga, jangan ragu untuk meminta klarifikasi.



9
"Contoh-contoh ini tidak acak. Cobalah lampirkan beberapa hal penting." Apa artinya?
Alex A.

3
Sebenarnya, seseorang tidak perlu angka heksadesimal, 10-base juga bisa acak. Misalnya, 12345678-1234-1234-1234-123456789012harus UUID yang valid (atau apakah ada hex digit yang diperlukan?). Apakah Anda menganggap ini celah?
Voitcus

3
Judul dan kalimat pertama menunjukkan bahwa Anda menginginkan UUID kanonik, dan contoh yang diberikan tampaknya mengikuti spesifikasi untuk UUID, tetapi Anda tampaknya meminta sesuatu yang lain.
Peter Taylor

3
Saya merasa terdorong untuk menunjukkan bahwa versi 4 (acak) UUID memiliki format yang diperlukan di xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx mana ysalah satunya [89AB]. Pada saat komentar ini, tidak ada jawaban (kecuali C # menggunakan built in library) dijamin untuk menghasilkan UUID acak yang valid (dan sebenarnya, sangat mungkin untuk tidak menghasilkan satu).

Jawaban:


11

Pyth, 20 byte

j\-msm.HO16*4hdj83 3

Demonstrasi.

Dikodekan [1, 0, 0, 0, 2]sebagai 83 di basis 3, lalu tambahkan satu dan kalikan dengan empat untuk mendapatkan panjang setiap segmen. Kemudian buat angka hex dan gabungkan dengan tanda hubung.


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

Hasilkan integer 128-bit acak, dapatkan representasi heksideksimalnya sebagai string yang diisi hingga 32 digit, dan bagi yang menjadi segmen yang digabungkan dengan tanda hubung.

Terima kasih kepada ConfusedMr_C dan kvill atas bantuan mereka!


8

CJam, 26 25 byte

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

Cobalah online di penerjemah CJam .

Bagaimana itu bekerja

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

sunting: parens asing:

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

sunting: mampu menghapus trailing .Trim ("-") dari aslinya:

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

Mungkin lebih jelas dengan spasi putih mengingat sifat dari flag (-f dan -Join). Saya masih ingin kehilangan Trim akhir ("-"):

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

Atau, menggunakan fungsi bawaan (ala C # jawaban di atas)

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

Namun, sepertinya sedikit pintas-y bahkan jika itu datang pada 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])

Ini memformat string pemformat untuk membuat format Python angka hex unik untuk setiap segmen.

Tidak Disatukan:

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

Ini bisa menggunakan beberapa perbaikan, tapi saya bangga.



4

PHP, 69 72 75 byte

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

Ini tidak menampilkan digit hex ( a, ... f). Mereka diizinkan, tetapi tidak diharuskan oleh badan pertanyaan.

Grup digit tidak dimulai dengan 0(juga tidak diperlukan).

sunting: disimpan 3 byte berkat @IsmaelMiguel


Itu terlihat seperti bi lebih dari 32 byte.
isaacg

@isaacg ya, maaf - kesalahan saya
Voitcus

Anda harus menggunakannya join()sebagai gantinya.
Ismael Miguel

3

C #, 65 Bytes

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

edit: Ya! C # lebih pendek dari Bahasa lain (selain Jawa) :)


1
Saya pikir ini dianggap sebagai celah standar ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings

1
Saya pikir ini tidak dianggap sebagai celah standar: Seperti yang Anda lihat permintaan untuk mengabaikan hal ini hanya mendapat 2 upvotes dalam lebih dari 1 tahun. Sebaliknya, komentar yang mengatakan bahwa Anda harus menggunakan fungsi bawaan mendapat 58 upvotes. Atau seperti yang dikatakan oleh seorang komentator -> Jika kita semua terbatas pada rangkaian fungsi bawaan yang sama, setiap kontes akan dimenangkan oleh APL atau Golfscript karena nama perintah mereka adalah yang terpendek. (Michael Stern)
Stephan Schinkel

1
atau dengan kata lain: Bisakah kita menggunakan printf? atau haruskah kita menggunakan inline asm untuk memicu interupsi 21?
Stephan Schinkel

Poin yang bagus! Saya tidak bermaksud kesal, saya hanya bermaksud membantu! Kalau begitu, Mathematica bisa menang CreateUUID[]!
Dom Hastings

1
@StephanSchinkel The "only 2 upvotes in a year" menyesatkan. Ini memiliki 47 upvotes dan 45 downvotes sekarang, jadi bersih +2. Yang sedang berkata, ambang yang diterima secara umum lebih tinggi dari itu, jadi Anda benar bahwa itu tidak "benar-benar" dianggap sebagai celah standar sekarang.
Geobits

3

melongo, 86

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

Anda dapat menggunakan ini setiap detik untuk menghasilkan "UUID" acak yang unik. Ini karena srand()menggunakan waktu sistem dalam detik sejak zaman sebagai argumen jika tidak ada argumen yang diberikan.

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

Saya pikir bagian awk agak elegan.

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

Jika Anda ingin menggunakannya lebih sering dari sekali setiap detik, Anda dapat menyebutnya di bash seperti ini. Perhatikan bahwa bagian awk juga berubah.

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

Itu echoditambahkan di sana untuk mencetak baris baru setiap kali.


3

K5, 35 byte

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

Untuk menghasilkan hex alphabet saya menghasilkan string karakter ( `c$) dari daftar digit ( 48+!10) dan 6 huruf kapital pertama ( 65+!6). Cara alternatif untuk menghasilkan digit dengan panjang yang sama adalah ,/$!10.

Dengan string "0123456789ABCDEF" dihasilkan, sisanya sederhana. Pilih 32 nilai acak dari set ini ( 32?), iris ( _) string yang dihasilkan pada 0 8 12 16 20dihitung melalui (0,8+4*!4), dan kemudian bergabung dengan fragmen string yang dihasilkan dengan tanda hubung ( "-"/).

Beraksi:

  "-"/(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='')

Cobalah online!

Pertama kode membangun string acak 36 karakter, dan kemudian menempatkan empat tanda hubung. Ini menghasilkan UUID ke stdout.


Ganti cpanggilan dengan sprintf("%x",0:15)untuk -1.
J.

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

Menggunakan Regex ganti. Memperlakukan string format sebagai hitungan untuk menghasilkan hex char. Mengangkat ke mana pun saya bisa; menghilangkan titik koma jika memungkinkan.


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

Yang jelas:

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

Menerjemahkan contoh Perl 5 menggunakan printf, menghasilkan kode yang sedikit lebih pendek.

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

(0..16⁴)?! Anda dapat melakukannya di Perl?
tepuk tangan

1
@VoteToSpam Anda dapat mulai 9 hari yang lalu . (Perl 6 akan dirilis akhir bulan ini)
Brad Gilbert b2gills

Cooooool. Mungkin saya harus mempelajarinya
bertepuk tangan

@VoteToSpam Itu tidak seberapa dibandingkan dengan 1,2,4,8,16 ... *yang menghasilkan daftar malas dari kekuatan 2. ( {2**$++} ... *juga berfungsi)
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)}

Cobalah online!

Program Kotlin & pengajuan PPCG pertama saya


152 bytes -> 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

Cobalah online!

Ini adalah pengajuan APL pertama saya. Terima kasih banyak kepada @ Adám karena mendukung saya di obrolan APL PPCG dan untuk fungsi konversi heksadesimal.

Terima kasih kepada @ Zacharý untuk 1 byte

Diedit untuk memperbaiki jumlah byte.


Anda dapat mengasumsikan ⎕IO←0tanpa biaya byte, AdAm melakukan itu banyak. Juga, sebagian besar byte (IIRC, semua yang Anda miliki di sini) dapat dihitung sebagai satu di APL.
Zacharý

@ Zacharý Saya telah menggunakan TIO untuk menghitung byte untuk pengiriman saya, haruskah saya menggunakan jumlah karakter saja? Saya masih baru untuk PPCG dan menggunakan APL, jadi saya tidak memiliki banyak pengetahuan aktual tentang bagaimana melakukan byte byte untuk itu.
J. Sallé

Juga, Anda dapat mengubah a(H 12?16)ke a H 12?16untuk menyimpan satu byte.
Zacharý


2

Japt , 32 byte

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

Cobalah online!


Selamat datang di PPCG dan selamat datang di Japt :) Saya akan menjalankan solusi Anda sejauh ini ketika saya dapat meluangkan waktu (baru saja kembali dari liburan, begitu banyak untuk mengejar ketinggalan) tetapi tip pertama yang akan saya tawarkan adalah membiasakan diri diri Anda dengan pintasan Unicode ( m@- £, misalnya) dan, untuk membantu Anda memulai, inilah versi 24 byte yang tergesa-gesa dari solusi Anda: ethproductions.github.io/japt/… Masuklah ke ruang obrolan Japt jika Anda memiliki pertanyaan.
Shaggy

1

MATLAB / Oktaf, 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

Membutuhkan perl5> = 5.10 Saya pikir. Untuk modifier / r dan untuk say ().


1
Bagus! Itu jauh lebih baik daripada milikku! Setelah melihat solusi Anda, Anda bahkan mungkin dapat menyimpan lebih banyak berdasarkan meta post ini dengan s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/egmenggunakan -pflag, juga berarti itu berfungsi pada versi yang lebih lama tanpa -E.
Dom Hastings

Terima kasih. Saran Anda adalah: echo | perl -pe // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg 'Dan itu hanya 48 karakter di antara' '. (Apakah ini jenis kecurangan? Mungkin tidak)
Kjetil S.

Menurut meta post ini bisa diterima, saya belum punya kesempatan untuk memanfaatkan mekanisme itu sendiri, tapi mudah-mudahan saya akan segera! Akan menjadi 49 byte (+ -p) tapi masih cukup bagus dan saya tidak akan mempertimbangkan pendekatan itu tanpa melihat jawaban Anda!
Dom Hastings


1

C ++, 194 193 221 210 201 byte

+7 byte berkat Zacharý (terdeteksi -yang seharusnya tidak di akhir)

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

Jika seseorang memiliki cara untuk mendapatkan nilai yang berbeda setiap eksekusi tanpa mengubah sranddan tanpa memasukkan <ctime>, itu akan bagus


Tidak bisa #define L(a) for... menjadi #define L(a)for...? (Mungkin sudah bertanya itu)
Zacharý

Ini tidak valid, ada "-" di akhir (yang seharusnya tidak ada)
Zacharý

@ Zacharý Koreksi diterapkan sekarang
HatsuPointerKun


1
Bisakah Anda melakukan sesuatu seperti "0123456789abcdef"[rand()%16], dan kemudian menghapus 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^

Cobalah online!

Saya yakin ini dapat menyusut, tetapi ini adalah percobaan pertama saya :)


1

Bash, 67 byte

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

Selamat datang di PPCG!
Dennis

1

JavaScript REPL, 79 byte

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

Cobalah online!

Math.randomdapat kembali 0. Menambahkan 5 nol membuat irisan mendapatkan 4 0detik


1

Keempat (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 ;

Cobalah online!

Penjelasan

Mengubah basis menjadi heksadesimal, kemudian menampilkan angka / segmen dengan panjang yang sesuai dengan tanda hubung pada interval yang ditentukan

Penjelasan Kode

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

Cobalah online!

Saya ingin menyarankan versi ini dalam komentar kepada Max Yekhlakov ( jawabannya ), tetapi sayangnya saya belum memiliki 50 poin reputasi yang dibutuhkan, jadi inilah jawaban saya.

803912 adalah C4448 dalam heksadesimal, hal itu menggambarkan bagaimana output harus diformat ( 12-4-4-4-8), itu terbalik karena paling signifikan digit akan dibaca pertama.
 

Suntingan:

  • disimpan 3 byte berkat Jonathan Frech
  • menyimpan 5 byte lebih banyak dengan mengganti srand(time(0))dengansrand(&i)

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

Saya telah memikirkan sesuatu, tampaknya srand()menerima unsigned intparameter seed-nya. Pada tio.run, panjangnya unsigned intadalah 4 byte tetapi UUID panjangnya 16 byte. Ini berarti hanya sebagian kecil dari output yang valid (1/2 ^ 12) akan dihasilkan, sehingga solusi saya (serta yang sebelumnya dengan time(0)) tidak valid. Bagaimana menurut anda ?
Annyo

Negara-negara OP Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. Entropi benih tidak selalu menentukan entropi RNG, meskipun kemungkinan besar tidak (tidak memeriksa srand()implementasinya). Namun, srand()sepengetahuan saya cukup seragam, jadi jika RNG itu sempurna, itu akan tetap seragam. Karena itu saya pikir jawaban Anda valid.
Jonathan Frech

Baik, saya mengerti. Saya juga bisa mengirimkan jawaban saya sebagai fungsi, dengan asumsi srand()sudah dilakukan, dan dalam hal ini tidak akan ada keraguan. Tapi saya tidak yakin apakah ini diperbolehkan, pengiriman C / C ++ lainnya semua tampaknya termasuk srand()int jawabannya (kecuali jika tidak digunakan rand())
Annyo


1

C (gcc), 143 110 103 96 94 byte

Golf turun ke 94 byte berkat ceilingcat dan 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));}

Cobalah online!

Penjelasan:

/*
  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
Halo dan selamat datang di PPCG! 110 byte .
Jonathan Frech

@JonathanFrech Terima kasih! Versi Anda sangat mengesankan!
Max Yekhlakov

Sarankan *z=L"\27\23\17\vz"alih-alih *z=L"\10\4\4\4\14"dan for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)bukannyafor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

Java dengan Ten Foot Laser Pole 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)));}

Diuji dengan versi 1.06 perpustakaan, tetapi ini harus bekerja dengan versi 1.04 atau lebih baru.



0

SmileBASIC, 65 62 byte

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

Saya membuat fungsi untuk mencetak 4 digit acak hex: DEF H?HEX$(RND(65536),4);:ENDserta 4 digit dengan -setelah mereka: DEF G:H?"-";:END. Maka hanya perlu memanggil fungsi-fungsi ini beberapa kali.


0

Chip , 109 + 6 = 115 byte

Membutuhkan bendera -wc36 , menyebabkan +6 byte

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

Cobalah online!

Menghasilkan 4 bit acak (empat ? 's) dan mengkonversi ke digit hex:

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

... sedikit tidak konvensional, tetapi itu menyelamatkan saya beberapa byte tanpa biaya untuk distribusi hasil.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.