I need a UUID. Your job is to generate one.

The canonical UUID (Universally Unique IDentifier) is a 32 digit hexadecimal number with hyphens inserted in certain points.The program should output 32 hex digits (128 bits), in the form of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (8-4-4-4-12 digits), where x is a random hexadecimal number. Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.


Generate 32 random hexadecimal digits in the form 8-4-4-4-12 digits. Shortest code wins.

EDIT: Must be hexadecimal. Always generating decimal only is invalid. EDIT 2: No built-ins. These aren't GUIDs, just generic hex digits.

Example output:


Input, and standard loopholes are disallowed.

This is , so shortest code wins. Also, feel free to ask for clarifications.

  • 5
    \$\begingroup\$ Seems like a less strict version of codegolf.stackexchange.com/q/32309/14215 \$\endgroup\$ – Geobits Sep 22 '15 at 4:09
  • 9
    \$\begingroup\$ "These examples are not random. Try to attach some significance." What does that mean? \$\endgroup\$ – Alex A. Sep 22 '15 at 4:15
  • 3
    \$\begingroup\$ Actually, one does not need hexadecimal numbers, 10-base can also be random. For example, 12345678-1234-1234-1234-123456789012 should be a valid UUID (or is any hex digit necessary?). Do you consider this a loophole? \$\endgroup\$ – Voitcus Sep 22 '15 at 7:26
  • 3
    \$\begingroup\$ The title and first sentence suggest that you want a canonical UUID, and the examples given appear to follow the spec for UUIDs, but you actually seem to be asking for something else. \$\endgroup\$ – Peter Taylor Sep 22 '15 at 8:48
  • 3
    \$\begingroup\$ I feel compelled to point out that the version 4 (random) UUID has a required format of xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx where y is one of [89AB]. At the time of this comment, none of the answers (except C# using a built in library) are guaranteed to produce a valid random UUID (and actually, are quite likely to not produce one). \$\endgroup\$ – user12166 Sep 22 '15 at 13:59

40 Answers 40


Pyth, 20 bytes

j\-msm.HO16*4hdj83 3


Encodes [1, 0, 0, 0, 2] as 83 in base 3, then adds one and multiplies by four to get the length of each segment. Then makes hex digits and joins on hyphens.


Julia, 80 bytes


Generate a random 128-bit integer, get its hexidecimal representation as a string padded to 32 digits, and divide that into segments joined with dashes.

Thanks to ConfusedMr_C and kvill for their help!


CJam, 26 25 bytes

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

Try it online in the CJam interpreter.

How it works

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.

PowerShell, 77 69 67 bytes


edit: extraneous parens:


edit: was able to remove the trailing .Trim("-") from the original:


It may be clearer with some whitespace given the nature of the flags (-f and -Join). I would still like to lose the final Trim("-"):

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

Or, using the built-in functionality (ala the C# answer above)


However, it seems a wee bit shortcut-y even if it comes in at 31 bytes.

  • \$\begingroup\$ 61 byte: (8,4,4,4,12|%{-join(1..$_|%{'{0:X}'-f(random(16))})})-join'-' \$\endgroup\$ – mazzy Aug 8 '18 at 12:48

Python 2, 86 84 bytes

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

This chains string formatters to make Python format the hex numbers uniquely for each segment.


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

This could use some improvement, but I'm proud.


Perl 5, 43 bytes

Saved 2 bytes thanks to @Xcali!

printf"%04x"."-"x/[2-5]/,rand 2**16for 1..8

Try it online!

  • 1
    \$\begingroup\$ Shaved two bytes, still using your basic method: Try it online! \$\endgroup\$ – Xcali Dec 8 '19 at 4:04
  • \$\begingroup\$ Thank you @Xcali! \$\endgroup\$ – Dom Hastings Dec 11 '19 at 14:00

PHP, 69 72 75 bytes

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

This does not output hex digits (a, ... f). They are allowed, but not required by the question body.

No digit group starts with 0 (also not required).

edit: saved 3 bytes thanks to @IsmaelMiguel

  • \$\begingroup\$ That looks like a bi more than 32 bytes. \$\endgroup\$ – isaacg Sep 22 '15 at 9:30
  • \$\begingroup\$ @isaacg yes, sorry - my mistake \$\endgroup\$ – Voitcus Sep 22 '15 at 9:31
  • \$\begingroup\$ You should use join() instead. \$\endgroup\$ – Ismael Miguel Sep 22 '15 at 13:25

C#, 65 Bytes

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

edit: Yes ! C# is shorter than another Language (besides Java) :)

  • 1
    \$\begingroup\$ I think this is considered a standard loophole... :( meta.codegolf.stackexchange.com/questions/1061/… \$\endgroup\$ – Dom Hastings Sep 22 '15 at 9:18
  • 1
    \$\begingroup\$ I think this is not considered a standard loophole: As you can see the request to abandon this stuff just got 2 upvotes in over 1 year. Contrarily the comment that says you should use built-in-functions got 58 upvotes. Or as one commenter said --> If we were all limited to the same set of built-in functions, every contest would be won by APL or Golfscript because their command names are the shortest. (Michael Stern) \$\endgroup\$ – Stephan Schinkel Sep 22 '15 at 9:40
  • 1
    \$\begingroup\$ or to just put it another way around: Can we use printf? or should we use inline asm to trigger interupt 21? \$\endgroup\$ – Stephan Schinkel Sep 22 '15 at 9:41
  • \$\begingroup\$ A good point! I didn't intend to upset, I only meant to be helpful! I guess then, Mathematica could win with CreateUUID[]! \$\endgroup\$ – Dom Hastings Sep 22 '15 at 11:02
  • 1
    \$\begingroup\$ @StephanSchinkel The "only 2 upvotes in a year" is misleading. It has 47 upvotes and 45 downvotes right now, so a net +2. That being said, the generally accepted threshold is higher than that, so you're right that it doesn't "really" count as a standard loophole right now. \$\endgroup\$ – Geobits Sep 22 '15 at 19:00

gawk, 86


You can use this once every second to generate a unique random "UUID". This is because srand() uses the system time in seconds since epoch as argument if there is no argument given.

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

I think the awk part is rather elegant.

    for(;j++<32;) {
        printf "%c", x
        if(j~"^8|12|16|20")printf "-"

If you want to use it more often than once every second you can call it in bash like this. Note that the awk part is changed too.

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

The echo is added there to print a new line every time.


K5, 35 bytes


To generate a hex alphabet I generate a character string (`c$) from a list of digits (48+!10) and the first 6 capital letters (65+!6). An alternate way of generating the digits which is the same length is ,/$!10.

With the string "0123456789ABCDEF" generated, the rest is simple. Select 32 random values from this set (32?), slice (_) the resulting string at 0 8 12 16 20 computed via (0,8+4*!4), and then join the resulting string fragments with dashes ("-"/).

In action:


R, 63 bytes


Try it online!

The code first builds a 36 character random string, and then places the four hyphens. It outputs a UUID to stdout.

  • \$\begingroup\$ Replace the c call with sprintf("%x",0:15) for -1. \$\endgroup\$ – J.Doe Oct 10 '18 at 9:31

JavaScript, ES6, 106 bytes

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

Uses Regex replace. Treats the format string as a count for generating a hex char. Hoisting wherever I can; omitting semicolons where possible.

  • \$\begingroup\$ 89 bytes, '8-4-4-4-12'.replace(/\d+/g,n=>Math.floor(16**n*Math.random()).toString(16).padStart(n,0)) \$\endgroup\$ – kamoroso94 Aug 29 '18 at 16:03

Perl 6, 53 bytes

The obvious one:

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

Translating the Perl 5 example using printf, results in code that is a bit shorter.

printf ($_='%04x')~"$_-"x 4~$_ x 3,(0..^4⁸).roll(8) # 53
  • \$\begingroup\$ (0..16⁴)?! You can do that in Perl? \$\endgroup\$ – clap Dec 3 '15 at 2:34
  • 1
    \$\begingroup\$ @VoteToSpam You can as of 9 days ago. ( Perl 6 will be released later this month ) \$\endgroup\$ – Brad Gilbert b2gills Dec 4 '15 at 15:29
  • \$\begingroup\$ Cooooool. Maybe I should learn it \$\endgroup\$ – clap Dec 4 '15 at 16:23
  • \$\begingroup\$ @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 ) \$\endgroup\$ – Brad Gilbert b2gills Dec 4 '15 at 16:29

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)

Try it online!

My first ever Kotlin program & PPCG submission


APL (Dyalog Unicode), 115 78 bytes

(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.

  • \$\begingroup\$ 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. \$\endgroup\$ – Zacharý Oct 19 '17 at 20:44
  • \$\begingroup\$ @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. \$\endgroup\$ – J. Sallé Oct 20 '17 at 12:42
  • \$\begingroup\$ Also, you can change a(H 12?16) to a H 12?16 to save one byte. \$\endgroup\$ – Zacharý Oct 20 '17 at 22:41
  • \$\begingroup\$ '-'@(+\9,3⍴5)⊢(⎕D,819⌶⎕A)[?36⍴16] or '-'@(+\9,3⍴5)∊⌂hex?18⍴256 \$\endgroup\$ – Adám Aug 6 '19 at 14:31

Japt, 32 bytes

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

Try it online!

  • \$\begingroup\$ 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. \$\endgroup\$ – Shaggy Aug 17 '18 at 9:14

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

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
    \$\begingroup\$ 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. \$\endgroup\$ – Dom Hastings Jul 17 '17 at 7:27
  • \$\begingroup\$ 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) \$\endgroup\$ – Kjetil S. Jul 17 '17 at 8:03
  • \$\begingroup\$ 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! \$\endgroup\$ – Dom Hastings Jul 17 '17 at 8:24

J, 42 39 37 27 bytes


Try it online!


C++, 194 193 221 210 201 bytes

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

#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

  • \$\begingroup\$ Can't #define L(a) for ... be #define L(a)for...? (Might have already asked that) \$\endgroup\$ – Zacharý Oct 19 '17 at 20:52
  • \$\begingroup\$ This is invalid, there's a "-" at the end (which there shouldn't be) \$\endgroup\$ – Zacharý Oct 20 '17 at 22:44
  • \$\begingroup\$ @Zacharý Correction applied now \$\endgroup\$ – HatsuPointerKun Oct 21 '17 at 8:55
  • \$\begingroup\$ 210 bytes \$\endgroup\$ – Zacharý Oct 21 '17 at 15:50
  • 1
    \$\begingroup\$ Could you do something like "0123456789abcdef"[rand()%16], and then remove f? \$\endgroup\$ – Zacharý Oct 22 '17 at 17:27

Befunge-93, 97 bytes

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

Try it online!

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


Bash, 67 bytes

for l in 4 2 2 2 6;{ o+=`xxd -p -l$l</dev/random`-;}
echo ${o::-1}
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Dennis Aug 5 '18 at 15:39

JavaScript REPL, 79 bytes


Try it online!

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


Forth (gforth), 91 89 bytes

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

Try it online!


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

C (gcc),  94   91  86 bytes


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.


  • saved 3 bytes thanks to Jonathan Frech
  • saved 5 more bytes by replacing srand(time(0)) with srand(&i)
  • 1
    \$\begingroup\$ main(){...;int i= can be main(i){...;i=. \$\endgroup\$ – Jonathan Frech Aug 8 '18 at 12:44
  • \$\begingroup\$ 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 ? \$\endgroup\$ – Annyo Aug 27 '18 at 7:49
  • \$\begingroup\$ 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. \$\endgroup\$ – Jonathan Frech Aug 27 '18 at 12:21
  • \$\begingroup\$ 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()) \$\endgroup\$ – Annyo Aug 27 '18 at 12:34
  • \$\begingroup\$ 81 bytes \$\endgroup\$ – ceilingcat Feb 8 '19 at 7:23

C (gcc), 143 110 103 96 94 bytes

Golfed down to 94 bytes thanks to ceilingcat and Jonathan Frech.


Try it online!


  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

        // increase the pointer and dereference it
             // 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
    \$\begingroup\$ Hello and welcome to PPCG! 110 bytes. \$\endgroup\$ – Jonathan Frech Aug 8 '18 at 7:16
  • \$\begingroup\$ @JonathanFrech Thank you! Your version is very impressive! \$\endgroup\$ – Max Yekhlakov Aug 8 '18 at 8:27
  • \$\begingroup\$ 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)) \$\endgroup\$ – ceilingcat Oct 9 '18 at 17:52

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.


Jelly, 17 bytes


Try it online!


SmileBASIC, 65 62 bytes

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

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.


Chip, 109 + 6 = 115 bytes

Requires flags -wc36, causing +6 bytes


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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.