Rastgele UUID oluştur


15

Bir UUID'ye ihtiyacım var. Senin işin bir tane yaratmak.

Standart UUID (Evrensel Benzersiz Tanımlayıcı), belirli noktalara tireler eklenmiş 32 basamaklı bir onaltılık sayıdır.Program , rastgele onaltılık bir sayı olan xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12basamak) şeklinde 32 onaltılık basamak (128 bit) vermelidir x. Dilinizin PRNG'sinin mükemmel olduğunu varsayarsak, tüm geçerli çıktıların üretilme olasılığı aynı olmalıdır.

TL; DR

Form 8-4-4-4-12basamaklarında 32 rastgele onaltılık basamak oluşturun . En kısa kod kazanır.

DÜZENLEME: Onaltılık olmalıdır. Her zaman yalnızca ondalık oluşturma geçersizdir. EDIT 2: Yerleşik yok. Bunlar GUID değil, sadece genel onaltılık basamaklardır.


Örnek çıktı:

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

Giriş ve standart boşluklara izin verilmiyor.


Bu , bu yüzden en kısa kod kazanır. Ayrıca, açıklama istemekten çekinmeyin.



9
"Bu örnekler rastgele değil. Biraz önem vermeye çalışın." Bu ne anlama geliyor?
Alex A.

3
Aslında, onaltılık sayılara ihtiyaç yoktur, 10 baz da rastgele olabilir. Örneğin, 12345678-1234-1234-1234-123456789012geçerli bir UUID olmalıdır (veya herhangi bir onaltılık basamak gerekli mi?). Bunun bir boşluk olduğunu düşünüyor musunuz?
Voitcus

3
Başlık ve ilk cümle kanonik bir UUID istediğinizi gösteriyor ve verilen örnekler UUID'lerin teknik özelliklerini takip ediyor gibi görünüyor, ancak aslında başka bir şey istiyor gibi görünüyorsunuz.
Peter Taylor

3
Ben sürüm 4 (rastgele) UUID gerekli bir biçimi olduğuna işaret mecbur hissediyorum xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx nerede ybiridir [89AB]. Bu yorum sırasında, cevapların hiçbirinin (yerleşik bir kütüphane kullanarak C # hariç) geçerli bir rastgele UUID üretmesi garanti edilmez (ve aslında bir tane üretmemesi olasıdır).

Yanıtlar:


11

Pyth, 20 bayt

j\-msm.HO16*4hdj83 3

Gösteri.

[1, 0, 0, 0, 2]Temel 3'te 83 olarak kodlar , ardından her segmentin uzunluğunu elde etmek için bir tane ekler ve dört ile çarpar. Sonra altıgen rakamlar yapar ve kısa çizgiler üzerinde birleşir.


8

Julia, 80 bayt

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

Rastgele 128 bitlik bir tamsayı oluşturun, onaltılık gösterimini 32 basamağa kadar doldurulmuş bir dize olarak alın ve bunu tire ile birleştirilen segmentlere bölün.

ConfusedMr_C ve kvill'e yardımları için teşekkürler!


8

CJam, 26 25 bayt

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

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

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 bayt

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

düzenleme: yabancı parens:

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

edit: sondaki .Trim ("-") orijinalinden kaldırıldı:

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

Bayrakların (-f ve -Join) doğası göz önüne alındığında bazı boşluklarla daha açık olabilir. Hala son Trim'i ("-") kaybetmek istiyorum:

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

Veya yerleşik işlevselliği kullanarak (yukarıdaki C # yanıtı)

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

Ancak, 31 baytta geliyor olsa bile, bir çiş kısayol-y gibi görünüyor.


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

5

Python 2, 86 84 bayt

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

Bu, Python'u her bir segment için onaltılık sayıları benzersiz bir şekilde biçimlendirmek için dize biçimlendiricilerini zincirler.

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

Bu biraz iyileşme sağlayabilir, ancak gurur duyuyorum.



4

PHP, 69 72 75 bayt

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

Bu, onaltılık basamaklar çıkarmaz ( a, ...f ) . Soru gövdesi tarafından izin verilir, ancak zorunlu değildir.

Hiçbir basamak grubu ile başlamaz 0(ayrıca gerekli değildir).

düzenleme: @IsmaelMiguel sayesinde 3 bayt kurtardı


Bu 32 bayttan daha fazla bi gibi görünüyor.
isaacg

@isaacg evet, üzgünüm - benim hatam
Voitcus

Bunun join()yerine kullanmalısınız .
Ismael Miguel

3

C #, 65 Bayt

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

düzenleme: Evet! C # başka bir dilden daha kısadır (Java dışında) :)


1
Bence bu standart bir boşluk olarak kabul ediliyor ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings

1
Bunun standart bir boşluk olduğunu düşünmüyorum: Bu şeyleri terk etme isteğini görebileceğiniz gibi, 1 yılda 2 upvotes aldım. Tam tersine yerleşik fonksiyonları kullanmanız gerektiğini söyleyen yorumda 58 oy var. Ya da bir yorumcunun dediği gibi -> Hepimiz aynı yerleşik işlevler setiyle sınırlı olsaydık, her yarışma APL veya Golfscript tarafından kazanılacaktı, çünkü komut adları en kısa. (Michael Stern)
Stephan Schinkel

1
ya da başka bir deyişle: printf kullanabilir miyiz? veya interupt 21'i tetiklemek için satır içi asm kullanmalı mıyız?
Stephan Schinkel

İyi bir nokta! Ben üzülmek niyetinde değildi, sadece yardımcı olmak istedim! Sanırım Mathematica kazanabilir CreateUUID[]!
Dom Hastings

1
@StephanSchinkel "Bir yılda sadece 2 upvotes" yanıltıcıdır. Şu anda 47 yukarı ve 45 aşağı oyuna sahip, bu yüzden net +2. Bununla birlikte, genel olarak kabul edilen eşik bundan daha yüksektir, bu yüzden şu anda standart bir boşluk olarak sayılmadığından haklısınız.
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}

Benzersiz bir rastgele "UUID" oluşturmak için bunu saniyede bir kullanabilirsiniz. Bunun nedeni srand(), herhangi bir argüman yoksa, çağrıyı argüman olarak bu yana saniye cinsinden kullanır.

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

Ben awk kısmı oldukça zarif olduğunu düşünüyorum.

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

Eğer saniyede bir kereden daha sık kullanmak isterseniz, bunu bash olarak arayabilirsiniz. Awk parçasının da değiştiğine dikkat edin.

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

echoYeni çizgisiyle her zaman yazdırmak için oraya eklenir.


3

K5, 35 bayt

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

Onaltılık alfabe oluşturmak için `c$rakam listesinden ( ) bir karakter dizesi ( ) oluşturuyorum48+!10 ) ve ilk 6 büyük harften ( 65+!6) . Aynı uzunlukta olan basamakları oluşturmanın alternatif bir yolu ,/$!10.

"0123456789ABCDEF" dizesi oluşturulduğunda, geri kalanı basittir. Bu kümeden ( 32?) 32 rastgele değer seçin _, sonuçta elde edilen dizeyi dilimleyin ( )0 8 12 16 20 hesaplanır(0,8+4*!4) ve sonra elde edilen dizgi parçalarını tire ("-"/ ) ile birleştirir.

Eylemde:

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

3

R , 63 bayt

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

Çevrimiçi deneyin!

Kod önce 36 karakterlik rastgele bir dize oluşturur ve ardından dört tireyi yerleştirir. Stdout'a bir UUID çıktısı verir.


cÇağrıyı sprintf("%x",0:15)-1 yerine değiştirin .
J.Doe

3

JavaScript, ES6, 106 bayt

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

Regex değişimini kullanır. Biçim dizesini onaltılı karakter oluşturmak için sayı olarak ele alır. Mümkün olan her yerde kaldırma; mümkün olduğunda noktalı virgül atlamak.


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

Açık olan:

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

Perl 5 örneğini kullanarak çevirmek printf, biraz daha kısa kodla sonuçlanır.

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

(0..16⁴)?! Bunu Perl'de yapabilir misin?
alkış

1
@VoteToSpam 9 gün önce yapabilirsiniz . (Perl 6 bu ayın sonlarında yayınlanacak)
Brad Gilbert b2gills

Cooooool. Belki bunu öğrenmelidir
alkış

Kıyasla hiçbir şeydir O @VoteToSpam 1,2,4,8,16 ... *hangi 2. yetkileri (tembel bir sonsuz listesini oluşturur {2**$++} ... *de çalışır)
Brad Gilbert b2gills

2

Kotlin , 175 bayt

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

Çevrimiçi deneyin!

İlk Kotlin programım ve PPCG başvurum


152 bayt -> tio.run/…
jrtapsell

2

APL (Dyalog Unicode) , 115 78 bayt

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

Çevrimiçi deneyin!

Bu benim ilk APL sunumum. @ Adám'a PPCG'nin APL sohbetinde yanımda olduğu ve onaltılık dönüşüm işlevi için çok teşekkürler.

1 byte için @ Zacharý'ya teşekkürler

Bayt sayısını düzeltmek için düzenlendi.


⎕IO←0Bayt bedeli ödemediğinizi varsayabilirsiniz , Adám bunu çok yapar. Ayrıca, çoğu bayt (IIRC, burada bulunanlar) APL'de bir tane olarak sayılabilir.
Zacharý

@ Zacharý Gönderim için baytları saymak için TIO'yu kullandım, bunun yerine karakter sayısını kullanmalıydım? Hala PPCG'de yeniyim ve APL kullanıyorum, bu yüzden bayt sayımının nasıl yapılacağı hakkında çok fazla bilgiye sahip değilim.
J. Sallé

Ayrıca, bir bayt kaydetmek a(H 12?16)için a H 12?16olarak değiştirebilirsiniz .
Zacharý


2

Japt , 32 bayt

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

Çevrimiçi deneyin!


PPCG'ye hoş geldiniz ve Japt'e hoş geldiniz :) Biraz zaman yapabileceğim (şimdiden tatillerden sonra, yetişmek için çok fazla) zaman şimdiye kadar çözümlerinizi gözden geçireceğim ama ilk önerim aşina olmak Unicode kısayolları ile kendinizi ( m@- £, örneğin) yardımına almak ve burada başladı senin çözümün bir aceleyle golfed 24 bayt sürümü: ethproductions.github.io/japt/... içine Bırak Japt chatroom sorularınız yasiyorsaniz.
Shaggy

1

MATLAB / Oktav, 95 bayt

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 bayt

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

Perl5 gerektirir> = 5.10 Sanırım. / R değiştiricisi ve say () için.


1
Güzel! Bu benimkinden çok daha iyi! Çözümünüz baktı, daha da fazla dayanan tasarruf mümkün olabilir bu meta yazı ile s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/egkullanarak -pbayrağı, ayrıca olmadan eski sürümlerinde çalışır anlamına gelecektir -E.
Dom Hastings

Teşekkürler. Öneriniz: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg 'Ve bu sadece 48 karakter arasında' '. (Bu tür bir hile mi? Belki değil)
Kjetil S.

Bu meta gönderiye göre kabul edilebilir, henüz bu mekanizmayı kendim kullanma fırsatım olmadı, ama umarım yakında yeteri kadar! 49 bayt (+ -p) ama yine de oldukça iyi olurdu ve cevabınızı görmeden bu yaklaşımı düşünmek olmazdı!
Dom Hastings


1

C ++, 194 193 221. 210 201 bayt

Zacharý sayesinde +7 bayt ( -sonunda olmaması gerektiği tespit edildi )

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

Birisinin değişmeden srandve dahil etmeden her yürütmede farklı bir değer elde etmesinin bir yolu varsa <ctime>, bu harika olurdu


Olamaz #define L(a) for... olamaz #define L(a)for...mı? (Bunu zaten sormuş olabilir)
Zacharý

Bu geçersiz, sonunda bir "-" var (olmamalı)
Zacharý

@ Zacharý Düzeltme uygulandı
HatsuPointerKun


1
Gibi bir şey yapabilir "0123456789abcdef"[rand()%16]ve sonra kaldırabilir fmisiniz?
Zacharý


1

Bash, 67 bayt

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

PPCG'ye Hoşgeldiniz!
Dennis

1

JavaScript REPL, 79 bayt

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

Çevrimiçi deneyin!

Math.randomdönebilir 0. 5 sıfır ekleyerek dilimleme 4 0s olsun


1

İleri (gforth) , 91 89 bayt

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

Çevrimiçi deneyin!

açıklama

Tabanı onaltılık olarak değiştirir, daha sonra belirtilen aralıklarda kesik çizgilerle uygun uzunlukta sayılar / segmentler çıkar

Kod Açıklaması

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 bayt

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

Çevrimiçi deneyin!

Max Yekhlakov'a ( cevabına ) yaptığı bir yorumda bu versiyonu önermek isterdim , ama ne yazık ki henüz gerekli 50 puanım yok, işte cevabım.

803912olduğu C4448çıkışı (nasıl biçimlendirilmesi gerektiğini onaltılık, bu açıklar 12-4-4-4-8azından önemli basamak ilk okunacak çünkü), bu tersine çevrilir.
 

Düzenlemeler:

  • Jonathan Frech sayesinde 3 bayt kurtardı
  • srand(time(0))ile değiştirerek 5 bayt daha kaydettisrand(&i)

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

Bir şey düşünüyordum, görünüşe göre srand()bir unsigned inttohum parametresi olarak kabul ediyorum . Tio.run'da an unsigned int4 bayt uzunluğunda, ancak UUID 16 bayt uzunluğundadır. Bu, geçerli çıktıların (1/2 ^ 12) yalnızca küçük bir kısmının oluşturulacağı anlamına gelir, bu nedenle çözümüm (önceki öncekinin yanı sıra time(0)) geçerli değildir. Ne düşünüyorsun ?
Annyo

OP belirtiyor Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. Tohum entropisi, muhtemelen muhtemelen ( srand()uygulamayı kontrol etmedi) rağmen, RNG entropisini belirlemez . Ancak, srand()bildiğim kadarıyla tekdüze, bu yüzden RNG mükemmel olsaydı, yine de tekdüze olurdu. Bu nedenle cevabınızın geçerli olduğunu düşünüyorum.
Jonathan Frech

Tamam anlıyorum. Ayrıca cevabımı srand()zaten yapılmış olduğunu varsayarak bir işlev olarak gönderebilirim ve bu durumda hiç şüphe olmayacak. Ancak, buna izin srand()rand()
verilip


1

C (GCC), 143 110 103 96 94 bayt

Tavan kedisi ve Jonathan Frech sayesinde 94 bayta indi.

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

Çevrimiçi deneyin!

Açıklama:

/*
  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
Merhaba ve PPCG'ye hoş geldiniz! 110 bayt .
Jonathan Frech

@JonathanFrech Teşekkür ederim! Versiyonunuz çok etkileyici!
Max Yekhlakov

Öner *z=L"\27\23\17\vz"yerine *z=L"\10\4\4\4\14"ve for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)yerinefor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

On Foot Lazer Kutuplu Java s. 1.06, 126 bayt

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

Kütüphanenin sürümü 1.06 ile test edilmiştir, ancak bu olmalı herhangi bir sürümü 1.04 veya daha yeni çalışırlar.



0

SmileBASIC, 65 62 bayt

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

: Ben 4 rastgele onaltılık basamak yazdırmak için bir işlevi oluşturulan DEF H?HEX$(RND(65536),4);:ENDbir yanı sıra 4 haneyi -peşlerinden: DEF G:H?"-";:END. O zaman sadece bu işlevleri birkaç kez çağırmak gerekir.


0

Yonga , 109 + 6 = 115 bayt

-wc36+6 bayta neden olan bayraklar gerektirir

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

Çevrimiçi deneyin!

4 rastgele bit (dördü ?) üretir ve onaltılık basamağa dönüştürür:

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

... biraz alışılmadık, ama sonuçların dağılımı için hiçbir ücret ödemeden beni biraz bayt kurtardı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.