Створити випадковий UUID


15

Мені потрібен UUID. Ваше завдання - створити один.

Канонічний UUID (Універсально унікальний ідентифікатор) - це 32-значне шістнадцяткове число з дефісами, вставленими в певних точках. Програма повинна виводити 32 шістнадцяткових цифр (128 біт) у вигляді xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12цифр), де xє випадкове шістнадцяткове число. Якщо припустити, що PRNG вашої мови є ідеальним, всі дійсні результати повинні мати однакову ймовірність створення.

TL; DR

Створіть 32 випадкові шістнадцяткові цифри у вигляді 8-4-4-4-12цифр. Найкоротший код виграє.

EDIT: Повинно бути шістнадцятковим. Завжди генерування лише десятків недійсне. EDIT 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
Схоже, менш сувора версія codegolf.stackexchange.com/q/32309/14215
Geobits

9
"Ці приклади не випадкові. Спробуйте надати деяке значення". Що це означає?
Олексій А.

3
Насправді, одному не потрібні шістнадцяткові числа, 10-базове також може бути випадковим. Наприклад, 12345678-1234-1234-1234-123456789012має бути дійсним UUID (чи потрібна будь-яка шістнадцятка цифр?). Ви вважаєте це лазівкою?
Voitcus

3
Заголовок і перше речення вказують на те, що ви хочете канонічного UUID, а наведені приклади, як видається, слідують специфікації для UUID, але ви, здається, вимагаєте чогось іншого.
Пітер Тейлор

3
Я змушений зазначити, що UUID версії 4 (випадковий) має необхідний формат, xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx де yце один [89AB]. На момент отримання цього коментаря жодна відповідь (за винятком C # за допомогою вбудованої бібліотеки) гарантовано не дає дійсного випадкового UUID (і насправді вони, ймовірно, не виробляють).

Відповіді:


11

Pyth, 20 байт

j\-msm.HO16*4hdj83 3

Демонстрація.

Кодує [1, 0, 0, 0, 2]як 83 в базі 3, потім додає один і множиться на чотири, щоб отримати довжину кожного сегмента. Потім робить шістнадцяткові цифри і приєднується до дефісів.


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). Я все одно хотів би програти остаточну обробку ("-"):

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

Або, використовуючи вбудований функціонал (аля відповідь C # вище)

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

Однак, здається, скороминуча клавіша-y, навіть якщо вона входить у 31 байт.


61 байт:(8,4,4,4,12|%{-join(1..$_|%{'{0:X}'-f(random(16))})})-join'-'
маззи

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(також не потрібно).

редагувати: збережено 3 байти завдяки @IsmaelMiguel


Це схоже на бі, що перевищує 32 байти.
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
Я думаю, що це не вважається стандартною лазівкою: як ви бачите, прохання відмовитися від цього матеріалу щойно отримало 2 оновлення протягом понад 1 року. Навпаки, коментар, який говорить про те, що слід використовувати вбудовані функції, отримав 58 відгуків. Або, як сказав один із коментаторів -> Якби ми всі обмежилися одним і тим же набором вбудованих функцій, кожен конкурс вигравав би APL або Golfscript, оскільки їхні імена команд найкоротші. (Майкл Стерн)
Стефан Шінкель

1
або просто кажучи про інше: Чи можемо ми використовувати printf? чи ми повинні використовувати вбудований ASM для запуску інтерп'юту 21?
Стефан Шінкель

Гарний момент! Я не збирався засмучуватися, я мав на увазі лише бути корисним! Я здогадуюсь тоді, Mathematica міг би перемогти CreateUUID[]!
Дом Гастінгс

1
@StephanSchinkel "Лише 2 оновлення за рік" вводять в оману. Зараз він має 47 оновлених і 45 нижніх, тому чистий +2. При цьому загальноприйнятий поріг вищий за це, тому ви маєте рацію, що зараз він не "справді" вважається стандартною лазівкою.
Геобіт

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

К5, 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})

Використовує заміну Regex. Розглядає рядок формату як кількість для генерування шістнадцяткових знаків. Підйом, куди я можу; опускаючи крапки з комою, де це можливо.


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 , 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⁴)?! Ви можете це зробити в Perl?
хлопайте

1
@VoteToSpam Ви можете станом на 9 днів тому . (Perl 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. Величезне спасибі @ Adám за те, що я переживав зі мною APL-чату PPCG і за шістнадцяткову функцію перетворення.

Завдяки @ Zacharý за 1 байт

Відредаговано, щоб виправити кількість байтів.


Ви можете припускати ⎕IO←0без байт, Adám робить це багато. Крім того, більшість байтів (IIRC, всі ті, що у вас є тут) можна вважати як один в APL.
Zacharý

@ Zacharý Я використовував TIO для підрахунку байтів для подання, чи повинен я замість цього використовувати кількість символів? Я все ще новачок у PPCG та використовую APL, тому я не маю особливих фактичних знань про те, як зробити кількість байтів для цього.
Дж. Салле

Крім того , ви можете змінити , a(H 12?16)щоб a H 12?16зберегти один байт.
Zacharý


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 / Октава, 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.
Дом Гастінгс

Спасибі. Ваша пропозиція: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / напр. "І це лише 48 знаків між '". (Це такий обман? Можливо, ні)
Kjetil S.

Згідно з цією мета-публікацією, це прийнятно, я ще не мав можливості використовувати цей механізм самостійно, але, сподіваюся, я скоро цього стану! Було б 49 байт (+ -p), але все-таки досить добре, і я б не вважав таким підходом, не бачивши вашої відповіді!
Дом Гастінгс


1

C ++, 194 193 221 210 201 байт

+7 байт завдяки Zacharý (виявлено, -що не повинно бути в кінці)

#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ý

@ Zacharý Виправлення застосовано зараз
HatsuPointerKun


1
Ви могли б зробити щось на кшталт "0123456789abcdef"[rand()%16], а потім зняти f?
Zacharý



1

JavaScript REPL, 79 байт

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

Спробуйте в Інтернеті!

Math.randomможе повернутися 0. Додавши 5 нулів, змусити нарізку отримати 4 0с


1

Четвертий (gforth) , 91 89 байт

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

Спробуйте в Інтернеті!

Пояснення

Змінює основу на шістнадцять, а потім виводить числа / відрізки відповідної довжини тиреми через задані інтервали

Пояснення коду

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

Спробуйте в Інтернеті!

Я хотів би запропонувати цю версію у коментарі до Макса Єхлакова ( його відповідь ), але, на жаль, у мене ще немає 50 потрібних балів репутації, тому ось моя відповідь.

803912знаходиться C4448в шістнадцятковій формі, вона описує, як слід форматувати висновок ( 12-4-4-4-8), він повертається назад, оскільки найменше значущі цифри будуть прочитані першими.
 

Зміни:

  • врятувало 3 байти завдяки Джонатану Фреху
  • збережено ще 5 байт, замінивши srand(time(0))наsrand(&i)

1
main(){...;int i=може бути main(i){...;i=.
Джонатан Фрех

Я щось думав, мабуть, srand()приймаю unsigned intпараметр як насіння. На tio.run довжина unsigned int4 байти, але UUID - 16 байт. Це означає, що генерується лише невелика частка дійсних результатів (1/2 ^ 12), тому моє рішення (як і попередній з time(0)) не є дійсним. Що ти думаєш ?
Анньо

ОП держав Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. Ентропія насіння не обов'язково визначає ентропію RNG, хоча це, швидше за все, (не перевірено srand()реалізацію). Однак, srand()наскільки мені відомо, досить рівномірно, так якби RNG був ідеальним, він все одно був би єдиним. Тому я вважаю, що ваша відповідь справедлива.
Джонатан Фрех

Добре, я зрозумів. Я також міг би подати свою відповідь як функцію, якщо припустити, що srand()це вже було зроблено, і в цьому випадку сумнівів не буде. Але я не впевнений, чи це дозволено, всі інші матеріали C / C ++, здається, містять відповідь srand()int (якщо не використовується rand())
Annyo


1

C (gcc), 143 110 103 96 94 байт

Поле на гольф до 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 байт .
Джонатан Фрех

@JonathanFrech Дякую! Ваша версія дуже вражає!
Макс Єхлаков

Запропонувати *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))
roofcat



0

SmileBASIC, 65 62 байти

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

Я створив функцію для друку 4 випадкових шістнадцятирічних цифр: 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 випадкових біта (чотири ?) і перетворює в шістнадцяткові цифри:

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

... трохи нетрадиційно, але це врятувало мені кілька байтів, не витрачаючи їх на розподіл результатів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.