ランダムUUIDを生成


15

UUIDが必要です。あなたの仕事はそれを生成することです。

正規のUUID(Universally Unique IDentifier)は、特定のポイントにハイフンが挿入された32桁の16進数です。プログラムは、32桁の16進数(128ビット)をxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx8-4-4-4-12digit)の形式で出力する必要があります。x。あなたの言語のPRNGが完璧であると仮定すると、すべての有効な出力は同じ確率で生成される必要があります。

TL; DR

32のランダムな16進数を数字の形式で生成し8-4-4-4-12ます。最短のコードが優先されます。

編集:16進数でなければなりません。常に小数のみを生成することは無効です。編集2:ビルトインなし。これらはGUIDではなく、一般的な16進数です。


出力例:

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

入力および標準の抜け穴は許可されません。


これはなので、最短のコードが優先されます。また、説明を求めてください。


5
あまり厳密バージョンのように思えるcodegolf.stackexchange.com/q/32309/14215
Geobits

9
「これらの例はランダムではありません。重要性を付けてみてください。」どういう意味ですか?
アレックスA.

3
実際には、16進数は必要ありません。10進数もランダムにすることができます。たとえば12345678-1234-1234-1234-123456789012、有効なUUID である必要があります(または、16進数が必要ですか?)。これは抜け穴だと思いますか?
ヴォイトカス

3
タイトルと最初の文は、正規のUUIDが必要であることを示しており、指定された例はUUIDの仕様に従っているように見えますが、実際には他の何かを求めているようです。
ピーターテイラー

3
バージョン4(ランダム)UUIDにはxxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where yisのいずれかの必須形式があることを指摘する必要があります[89AB]。このコメントの時点で、有効なランダムUUIDの生成が保証されている(組み込みライブラリを使用するC#を除く)ものはありません(実際には、生成されない可能性が非常に高い)。

回答:


11

Pyth、20バイト

j\-msm.HO16*4hdj83 3

デモンストレーション。

[1, 0, 0, 0, 2]ベース3で83としてエンコードし、1を加算して4で乗算して各セグメントの長さを取得します。次に、16進数を作成し、ハイフンで結合します。


8

ジュリア、80バイト

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

ランダムな128ビット整数を生成し、32桁に埋め込まれた文字列として16進表現を取得し、ダッシュで結合されたセグメントに分割します。

ConfusedMr_Cとkvillの協力に感謝します!


8

CJam、26 25バイト

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

CJamインタプリタでオンラインで試してください。

使い方

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バイト

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

編集:無関係な括弧:

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

編集:末尾の.Trim( "-")をオリジナルから削除できました:

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

フラグの性質(-fおよび-Join)を考慮すると、いくつかの空白を使用するとより明確になる場合があります。最終的なTrim( "-")を失いたい:

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

または、組み込みの機能を使用します(上記のC#回答)

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

ただし、31バイトで入ってきたとしても、ちょっとしたショートカットに見えます。


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

5

Python 2、86 84バイト

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

これにより、文字列フォーマッターがチェーンされ、Pythonが各セグメントの一意の16進数をフォーマットします。

ゴルフをしていない:

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

これはいくらか改善する可能性がありますが、私は誇りに思っています。



4

PHP、69 72 75バイト

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

これは16進数(a、...を出力しませんf)を。これらは許可されていますが、質問本文では必須ではありません。

で始まる数字グループはありません 0(必須ではありません)。

編集:@IsmaelMiguelのおかげで3バイト節約


これは、32バイトを超えるbiのように見えます。
isaacg

はい@isaacg、申し訳ありません-私のミス
Voitcus

join()代わりに使用する必要があります。
イスマエルミゲル

3

C#、65バイト

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

編集:はい!C#は(Java以外の)別の言語よりも短い:)


1
私は...これは、標準の抜け穴を考えられていると思う:( meta.codegolf.stackexchange.com/questions/1061/...
ドムヘイスティングス

1
これは標準的な抜け穴とは見なされていないと思います。このことを放棄する要求を見るとわかるように、1年以上で2つの賛成票を獲得しました。反対に、組み込み関数を使用する必要があるというコメントには、58の賛成票がありました。または、あるコメンターが言ったように->組み込み関数の同じセットに制限されている場合、コマンド名が最も短いため、すべてのコンテストはAPLまたはGolfscriptによって勝ち取られます。(マイケル・スターン)
ステファンシンケル

1
または単に別の言い方をすれば、printfを使用できますか?または、インラインasmを使用して割り込み21をトリガーする必要がありますか?
ステファンシンケル

良い点!私は動揺するつもりはありませんでした、私は助けになるだけでした!Mathematicaで勝つことができると思いCreateUUID[]ます!
ドムヘイスティングス

1
@StephanSchinkel「1年にたった2回の賛成票」は誤解を招きます。現在、47のアップ投票と45のダウン投票があるため、正味+2です。とはいえ、一般に受け入れられているしきい値はそれよりも高いため、現時点では「本当に」標準的な抜け穴としてカウントされないのは正しいことです。
ジオビット

3

gawk、86

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

これを毎秒1回使用して、一意のランダムな「UUID」を生成できます。これは、srand()引数が指定されていない場合、エポック以降のシステム時間を引数として使用するためです。

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

awkの部分はかなりエレガントだと思います。

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

1秒に1回よりも頻繁に使用する場合は、このようにbashで呼び出すことができます。awk部分も変更されていることに注意してください。

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

echo新しい行を毎回印刷することが追加されます。


3

K5、35バイト

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

16進数のアルファベットを生成するに`c$は、数字のリスト(48+!10)と最初の6つの大文字()から文字列()を生成します65+!6。同じ長さの数字を生成する別の方法は,/$!10です。

文字列「0123456789ABCDEF」が生成されると、残りは簡単です。このセットから32個のランダムな値を選択し(32?)、を介し_0 8 12 16 20計算された結果の文字列をスライスし()、(0,8+4*!4)ダッシュで結果の文字列フラグメントを結合します("-"/)。

動作中:

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

3

R、63バイト

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

オンラインでお試しください!

コードは最初に36文字のランダムな文字列を作成し、次に4つのハイフンを配置します。UUIDをstdoutに出力します。


cコールをsprintf("%x",0:15)-1に置き換えます。
J.Doe

3

JavaScript、ES6、106バイト

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

正規表現の置換を使用します。書式文字列を16進文字を生成するためのカウントとして扱います。可能な限り巻き上げます。可能な限りセミコロンを省略します。


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

2

Perl 6バイト

明らかなもの:

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

を使用してPerl 5の例を翻訳するとprintf、コードが少し短くなります。

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

(0..16⁴)?!Perlでそれを行うことができますか?
クラップ

1
@VoteToSpam 9日前までにできます。(Perl 6は今月後半にリリースされます)
ブラッドギルバートb2gills

ちょー たぶんそれを学ぶ必要があります
クラップ

比べてのものということ@VoteToSpam 1,2,4,8,16 ... *たが、2のべき乗(の怠惰な無限のリストを生成していない{2**$++} ... *にも作品)
ブラッド・ギルバートがb2gills


2

APL(Dyalog Unicode)115 78 バイト

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

オンラインでお試しください!

これは私の最初のAPL提出です。PPCGのAPLチャットに参加してくれて、16進数変換機能を提供してくれた@Adámに感謝します。

1バイトの@Zacharýに感謝

バイトカウントを修正するために編集されました。


⎕IO←0バイトコストなしで、Adámが多くを行うと仮定できます。また、ほとんどのバイト(IIRC、ここにあるすべてのバイト)はAPLで1バイトとしてカウントできます。
ザカリー

@ZacharýTIOを使用して送信のバイト数をカウントしましたが、代わりに文字数を使用する必要がありますか?私はまだPPCGとAPLを使用したことがないので、バイトカウントの実行方法に関する実際の知識はあまりありません。
J.サール

また、1バイトを保存a(H 12?16)するa H 12?16ように変更できます。
ザカリー


2

Japt、32バイト

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

オンラインでお試しください!


PPCGにようこそ、Japtにようこそ:)少し時間をとることができたら(休日から戻って、追いつくためにたくさん)、これまでのソリューションを試してみますが、最初のヒントは慣れることですUnicodeのショートカットを自分で(m@- £、たとえば)ヘルプを取得し、あなたはここで開始し、ソリューションの急いでgolfed 24バイトバージョンです:ethproductions.github.io/japt/...にドロップJAPTチャットルーム何か質問をした場合。
シャギー

1

MATLAB / Octave、95バイト

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バイト

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

perl5> = 5.10が必要です。/ r修飾子およびsay()の場合。


1
いいね!それは私のものよりもはるかに良いです!あなたのソリューションを見れば、フラグを使用してこのメタ投稿に基づいてさらに節約できるかもしれません。s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/eg-p-E
ドムヘイスティングス

ありがとう。あなたの提案は次のとおりです。(不正行為のこの一種であるかもしれない?)
はKjetil S.

このメタ投稿によると、それは許容範囲内であり、私はまだ自分でそのメカニズムを利用する機会はありませんでしたが、うまくいけばすぐに十分になるでしょう!49バイト(+ -p)になりますが、それでもかなり良いので、あなたの答えを見ることなく、そのアプローチを検討しなかったでしょう!
ドムヘイスティングス


1

C ++、194の 193 221 210 201バイト

Zacharýのおかげで+7バイト(-最後にあるべきではないものが検出された)

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

誰かが変更srandせずに含めることなく、実行ごとに異なる値を取得する方法がある場合<ctime>、それは素晴らしいことです


ことはできません#define L(a) for...こと#define L(a)for...?(既にそれを求めている可能性があります)
ザカリー

これはあり、無効である「 - 」最後で(あってはならないもの)
ザカリー

@Zacharý修正が適用されました
HatsuPointerKun


1
次のようなことをして"0123456789abcdef"[rand()%16]から削除できますfか?
ザカリー


1

Bash, 67 bytes

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

Welcome to PPCG!
Dennis

1

JavaScript REPL, 79 bytes

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

Try it online!

Math.random may return 0. Adding 5 zeros make the slicing get 4 0s


1

Forth (gforth), 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 ;

Try it online!

Explanation

Changes the base to hexadecimal, then outputs numbers/segments of the appropriate length with dashes at specified intervals

Code Explanation

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

Try it online!

I would have liked to suggest this version in a comment to Max Yekhlakov (his answer), but unfortunately I do not have the 50 needed reputation points yet, so here is my answer.

803912 is C4448 in hexadecimal, it describes how the output should be formatted (12-4-4-4-8), it is reversed because least significant digits will be read first.
 

Edits:

  • saved 3 bytes thanks to Jonathan Frech
  • saved 5 more bytes by replacing srand(time(0)) with srand(&i)

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

I've been thinking something, apparently srand() accept an unsigned int as its seed parameter. On tio.run, an unsigned int is 4 bytes long but the UUID is 16 bytes long. This means only a tiny fraction of the valid outputs (1/2^12) will be generated, thus my solution (as well as the previous one with time(0)) is not valid. What do you think ?
Annyo

The OP states Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. The seed entropy does not necessarily determine the RNG entropy, though it likely does (did not check the srand() implementation). However, srand() is to my knowledge reasonably uniform, so if the RNG was perfect, it would still be uniform. I therefore think your answer is valid.
Jonathan Frech

Ok, I understand. I could also submit my answer as a function, assuming srand() has already been done, and in this case there will be no doubt. But I'm not sure if this is allowed, other C/C++ submissions all seem to include srand() int the answer (unless it does not use rand())
Annyo


1

C (gcc), 143 110 103 96 94 bytes

Golfed down to 94 bytes thanks to ceilingcat and 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));}

Try it online!

Explanation:

/*
  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
Hello and welcome to PPCG! 110 bytes.
Jonathan Frech

@JonathanFrech Thank you! Your version is very impressive!
Max Yekhlakov

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

1

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

Tested with version 1.06 of the library, but this should work with any version 1.04 or newer.



0

SmileBASIC, 65 62 bytes

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

I created a function to print 4 random hex digits: DEF H?HEX$(RND(65536),4);:END as well as 4 digits with a - after them: DEF G:H?"-";:END. Then it just has to call these functions a bunch of times.


0

Chip, 109 + 6 = 115 bytes

Requires flags -wc36, causing +6 bytes

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

Try it online!

Generates 4 random bits (the four ?'s) and converts to hex digits:

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

...a bit unconventional, but it saved me some bytes at no expense to the distribution of outcomes.

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.