生成随机UUID


15

我需要一个UUID。您的工作是生成一个。

规范的UUID(通用唯一标识符)是一个32位十六进制数字,在某些点上插入了连字符。程序应输出32位十六进制数字(128位),格式为 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx8-4-4-4-12位数),其中x是一个随机十六进制数。假设您的语言的PRNG是完美的,则所有有效输出必须具有相同的生成概率。

TL; DR

生成以下形式的32个随机十六进制数字 8-4-4-4-12数字数字。最短的代码获胜。

编辑:必须为十六进制。始终仅生成小数是无效的。编辑2:没有内置。这些不是GUID,只是通用的十六进制数字。


输出示例:

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

9
“这些例子不是随机的。尝试附加一些意义。” 这意味着什么?
Alex A.

3
实际上,一个不需要十六进制数,以10为底的整数也可以是随机的。例如,12345678-1234-1234-1234-123456789012应为有效的UUID(或是否需要任何十六进制数字?)。您认为这是一个漏洞吗?
Voitcus

3
标题和第一句建议您使用规范的UUID,给出的示例似乎符合UUID的规范,但实际上您似乎在要求其他内容。
彼得·泰勒

3
我不得不指出,版本4(随机)UUID的必填格式是xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where y之一[89AB]。在发表此评论时,没有任何答案(使用内置库的C#除外)不能保证产生有效的随机UUID(实际上,很可能不会产生任何答案)。

Answers:


11

Pyth,20个字节

j\-msm.HO16*4hdj83 3

示范。

[1, 0, 0, 0, 2]在基数3中编码为83,然后加1并乘以4得到每个段的长度。然后使十六进制数字并连字符。


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位数字的字符串的形式获取其十六进制表示形式,并将其划分为带破折号的段。

感谢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个字节,它似乎还是有点捷径-y。


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为每个段唯一地格式化十六进制数字。

取消高尔夫:

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

这不会输出十六进制数字(a,...f)。它们是允许的,但问题正文不是必需的。

没有数字组以 0(也不是必需的)。

编辑:由于@IsmaelMiguel而节省了3个字节


看起来bi超过32个字节。
isaacg

@isaacg是的,很抱歉-我的错误
Voitcus

您应该join()改用。
Ismael Miguel 2015年

3

C#,65个字节

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

编辑:是的!C#比另一种语言(Java除外)短:)


1
我认为这是一个标准漏洞... :( meta.codegolf.stackexchange.com/questions/1061/…–
Dom Hastings

1
我认为这不是一个标准漏洞:如您所见,放弃此内容的请求在一年多的时间内获得了2次支持。相反,说您应该使用内置功能的评论得到58票赞成。或如一位评论者所说->如果我们都限于同一组内置函数,那么APL或Golfscript会赢得所有比赛,因为它们的命令名最短。(迈克尔·斯特恩)
斯蒂芬·辛克尔

1
或换种说法:我们可以使用printf吗?还是应该使用内联汇编来触发Interupt 21?
Stephan Schinkel

好点!我无意沮丧,我只是想提供帮助!我想那Mathematica可以赢了CreateUUID[]
Dom Hastings

1
@StephanSchinkel“一年中只有2次投票”具有误导性。它现在有47个赞成票和45个反对票,因此净+2。话虽这么说,公认的阈值高于该阈值,所以您说对了,它现在还没有“真正”算作标准漏洞。
Geobits 2015年

3

高夫,86

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

您可以每秒使用一次,以生成唯一的随机“ 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 "-"
    }
}

如果您希望使用它的频率超过每秒一次,可以像这样在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

要生成十六进制字母,我需要`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个字符的随机字符串,然后放置四个连字符。它将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})

使用正则表达式替换。将格式字符串视为生成十六进制字符的计数。尽我所能吊起;尽可能省略分号。


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

2

Perl 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⁴)?! You can do that in Perl?
clap

1
@VoteToSpam You can as of 9 days ago. ( Perl 6 will be released later this month )
Brad Gilbert b2gills

Cooooool. Maybe I should learn it
clap

@VoteToSpam That's nothing compared to 1,2,4,8,16 ... * which generates a lazy infinite list of the powers of 2. ( {2**$++} ... * also works )
Brad Gilbert b2gills

2

Kotlin, 175 bytes

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

Try it online!

My first ever Kotlin program & PPCG submission


152 bytes -> tio.run/…
jrtapsell

2

APL (Dyalog Unicode), 115 78 bytes

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

Try it online!

This is my first APL submission. Huge thanks to @Adám for bearing with me at the PPCG's APL chat and for the hexadecimal conversion function.

Thanks to @Zacharý for 1 byte

Edited to fix byte count.


You can assume ⎕IO←0 at no byte cost, Adám does that alot. Also, most bytes (IIRC, all the ones you have here) can be counted as one in APL.
Zacharý

@Zacharý I've used TIO to count the bytes for my submission, should I have used the number of characters instead? I'm still new to PPCG and using APL, so I don't have much actual knowledge of how to do the byte count for it.
J. Sallé

Also, you can change a(H 12?16) to a H 12?16 to save one byte.
Zacharý


2

Japt, 32 bytes

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

Try it online!


Welcome to PPCG and welcome to Japt :) I'll take a run through your solutions so far when I can make some time (just back from holidays, so much to catch up on) but the first tip I'll offer is to familiarise yourself with the Unicode shortcuts (m@ - £, for example) and, to help get you started here's a hastily golfed 24 byte version of your solution: ethproductions.github.io/japt/… Drop into the Japt chatroom if you've any questions.
Shaggy

1

MATLAB/Octave , 95 bytes

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 bytes

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

Requires perl5 >= 5.10 I think. For the /r modifier and for say().


1
Nice! That's much better than mine! Having looked at your solution, you might even be able to save more based on this meta post with s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/eg using -p flag, would also mean it works on older versions without -E.
Dom Hastings

Thanks. Your suggestion is: echo|perl -pe's//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/eg' And thats just 48 chars between ' '. (Is this kind of cheating? Maybe not)
Kjetil S.

According to this meta post it's acceptable, I haven't had an opportunity to utilise that mechanism myself yet, but hopefully I will soon enough! Would be 49 bytes (+ -p) but still pretty good and I wouldn't have considered that approach without seeing your answer!
Dom Hastings


1

C++, 194 193 221 210 201 bytes

+7 bytes thanks to Zacharý ( detected a - that should not be at the end )

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

If someone has a way to get a different value every execution without changing srand and without including <ctime>, that would be great


Can't #define L(a) for ... be #define L(a)for...? (Might have already asked that)
Zacharý

This is invalid, there's a "-" at the end (which there shouldn't be)
Zacharý

@Zacharý Correction applied now
HatsuPointerKun


1
Could you do something like "0123456789abcdef"[rand()%16], and then remove f?
Zacharý

1

Befunge-93, 97 bytes

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

Try it online!

I'm sure this can be shrunk, but this is my first try :)


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.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.