임의의 UUID 생성


15

UUID가 필요합니다. 당신의 직업은 하나를 생성하는 것입니다.

표준 UUID (Universally Unique IDentifier)는 특정 지점에 하이픈이 삽입 된 32 자리 16 진수 숫자이며, 프로그램은 임의의 16 진수 숫자 인 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12자리수) 형식으로 32 개의 16 진수 (128 비트)를 출력해야합니다 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
"이러한 예는 무작위가 아닙니다. 중요한 의미를 부여하십시오." 그게 무슨 뜻이야?
Alex A.

3
실제로, 16 진수는 필요하지 않으며 10-base는 임의적 일 수 있습니다. 예를 들어 12345678-1234-1234-1234-123456789012유효한 UUID 여야합니다 (또는 16 진수가 필요합니까?). 이것을 허점으로 생각하십니까?
Voitcus

3
제목과 첫 문장은 표준 UUID를 원한다고 제안하고 주어진 예제는 UUID의 스펙을 따르는 것으로 보이지만 실제로 다른 것을 요구하는 것 같습니다.
피터 테일러

3
버전 4 (임의의) UUID에 필수 형식이 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where y중 하나임 을 지적해야합니다 [89AB]. 이 의견을 제출할 당시에 (내장 라이브러리를 사용하는 C #을 제외하고) 어떤 답변도 유효한 임의의 UUID를 생성한다고 보장하지 않으며 실제로는 UUID를 생성하지 않을 가능성이 높습니다.

답변:


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 비트 정수를 생성하고 16 진수 표현을 32 자리로 채워진 문자열로 얻은 다음 대시로 연결된 세그먼트로 나눕니다.

도움을 주신 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"-"

편집 : 외래의 parens :

((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)의 특성에 따라 일부 공백이 더 명확 할 수 있습니다. 여전히 최종 트림 ( "-")을 잃고 싶습니다.

(((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'-'
매기

5

파이썬 2, 86 84 바이트

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

이것은 문자열 포맷터를 연결하여 각 세그먼트에 대해 고유하게 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()대신 사용해야 합니다.
Ismael Miguel

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가 모든 대회에서 우승 할 것입니다. (Michael Stern)
Stephan Schinkel

1
아니면 다른 방법으로 넣을 수도 있습니다 : printf를 사용할 수 있습니까? 또는 인라인 asm을 사용하여 interupt 21을 트리거해야합니까?
Stephan Schinkel

좋은 지적이야! 나는 화 내려고하지 않았다. 나는 단지 도움이 되려고했다! 나는 Mathematica가 이길 수 있다고 생각한다 CreateUUID[]!
Dom Hastings

1
@StephanSchinkel "1 년에 단 2 개의 공감대"는 오해의 소지가 있습니다. 현재 47 개의 공감대와 45 개의 공감대가 있으므로 순 +2입니다. 즉, 일반적으로 허용되는 임계 값이 그 임계 값보다 높으므로 현재 표준 허점으로 "실제로"계산되지 않는 것이 맞습니다.
Geobits

3

개크, 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 회 이상 자주 사용하려면 다음과 같이 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 개의 하이픈을 배치합니다. stdout에 UUID를 출력합니다.


c통화 sprintf("%x",0:15)를 -1로 바꿉니다 .
J.Doe

3

자바 스크립트, 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 16:29 '08 :

2

펄 6 , 53 바이트

명백한 것 :

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⁴)?! 펄에서 그렇게 할 수 있습니까?
clap

1
@VoteToSpam 9 일 전부터 할 수 있습니다 . (펄 6은 이달 말 출시 예정)
브래드 길버트는 b2gills

Cooooool. 어쩌면 나는 그것을 배워야한다
박수 갈채

비교의 아무것도 그건 @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에서 하나로 계산 될 수 있습니다.
Zacharý

@ Zacharý TIO를 사용하여 제출 바이트 수를 계산했습니다. 대신 문자 수를 사용해야합니까? 나는 여전히 PPCG를 처음 사용하고 APL을 사용하고 있기 때문에 바이트 수를 수행하는 방법에 대한 실제 지식이별로 없습니다.
J. Sallé

또한, 당신은 변경할 수 있습니다 a(H 12?16)a H 12?16한 바이트를 저장합니다.
Zacharý



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

, 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
Dom Hastings

감사. 귀하의 제안은 : echo | perl -pe 's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / eg '그리고' '사이에 48 개의 문자입니다. (이런 종류의 부정 행위입니까? 아닐 수도 있습니다)
Kjetil S.

이 메타 포스트 에 따르면 , 나는 그 메커니즘을 아직 활용할 기회가 없었지만, 곧 충분할 것입니다! 49 바이트 (+ -p)이지만 여전히 꽤 좋으며 대답을 보지 않고는 그 접근법을 고려하지 않았을 것입니다!
Dom Hastings


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ý

이것은 거기, 무효 "-"마지막에 (이 안되는)
재커리

@ Zacharý 수정 적용
HatsuPointerKun


1
과 같은 작업을 수행 "0123456789abcdef"[rand()%16]한 다음 제거 할 수 f있습니까?
Zacharý


1

배쉬, 67 바이트

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

PPCG에 오신 것을 환영합니다!
Dennis

1

자바 스크립트 REPL, 79 바이트

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

온라인으로 사용해보십시오!

Math.random반환 될 수 있습니다 0. 5 개의 0을 추가하면 슬라이싱이 4 0초가됩니다.


1

넷째 ( 91 ) , 91 89 바이트

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

온라인으로 사용해보십시오!

설명

밑을 16 진수로 변경 한 다음 지정된 간격으로 대시와 함께 적절한 길이의 숫자 / 세그먼트를 출력합니다

코드 설명

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 바이트

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

온라인으로 사용해보십시오!

Max Yekhlakov ( 그의 답변 ) 에 대한 의견 으로이 버전을 제안 하고 싶지만 불행히도 아직 50 개의 평판이 필요하지 않으므로 여기에 내 대답이 있습니다.

803912이다 C4448출력 (포맷하는 방법 진수, 그것은 설명 12-4-4-4-8최하위 자리가 먼저 읽을 수 있기 때문에),이 반전됩니다.
 

편집 :

  • Jonathan Frech 덕분에 3 바이트 절약
  • 로 교체 srand(time(0))하여 5 바이트를 더 절약 했습니다.srand(&i)

1
main(){...;int i=일 수 있습니다 main(i){...;i=.
Jonathan Frech

나는 무언가를 생각하고 있었고, 분명히 씨앗 매개 변수로 srand()받아들 unsigned int입니다. tio.run에서의 unsigned int길이는 4 바이트이지만 UUID의 길이는 16 바이트입니다. 이것은 유효한 출력 (1 / 2 ^ 12)의 작은 부분 만 생성되므로 내 솔루션 (및 이전 솔루션 time(0))이 유효하지 않음을 의미합니다. 어떻게 생각해 ?
Annyo

OP 상태 Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.입니다. 시드 엔트로피는 RNG 엔트로피를 반드시 결정하지는 않지만 srand()구현을 확인하지는 못했을 것 입니다. 그러나 srand()내 지식은 합리적으로 균일하므로 RNG가 완벽하다면 여전히 균일합니다. 따라서 귀하의 답변이 유효하다고 생각합니다.
Jonathan Frech

알았어요 또한 srand()이미 완료 되었다고 가정하여 답변을 함수로 제출 할 수 있으며이 경우 의심의 여지가 없습니다. 그러나 이것이 허용되는지는 확실하지 않습니다. 다른 C / C ++ 제출에는 모두 srand()int가 답 을 포함하는 것으로 보입니다 (사용하지 않는 한 rand())
Annyo


1

C (GCC), 143 (110) 103 96 94 바이트

ceilingcat와 Jonathan Frech 덕분에 94 바이트로 줄었습니다.

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

온라인으로 사용해보십시오!

설명:

/*
  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
PPCG에 오신 것을 환영합니다! 110 바이트 .
Jonathan Frech

@JonathanFrech 감사합니다! 당신의 버전은 매우 인상적입니다!
Max Yekhlakov

제안 *z=L"\27\23\17\vz" 대신 *z=L"\10\4\4\4\14"하고 for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)대신for(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

Ten Foot Laser Pole을 지원하는 Java v. 1.06, 126 바이트

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

라이브러리의 버전 1.06으로 테스트, 그러나 이것은 해야 모든 버전 1.04 이상과 함께 작동합니다.



0

SmileBASIC, 65 62 바이트

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

4 개의 임의의 16 진수를 인쇄하는 기능 DEF H?HEX$(RND(65536),4);:END과 4 개의 숫자를 -뒤에 표시 하는 함수를 만들었습니다 DEF G:H?"-";:END. 그런 다음이 함수를 여러 번 호출하면됩니다.


0

, 109 + 6 = 115 바이트

-wc36+6 바이트를 발생시키는 플래그 필요

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

온라인으로 사용해보십시오!

4 개의 임의 비트 (4 개)를 생성 ?하고 16 진수로 변환합니다.

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

... 비 전통적이지만 결과 분배에 비용을 들이지 않고 약간의 바이트를 절약했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.