Generiere zufällige UUID


15

Ich brauche eine UUID. Ihre Aufgabe ist es, eine zu generieren.

Die kanonische UUID (Universally Unique IDentifier) ​​ist eine 32-stellige Hexadezimalzahl mit Bindestrichen an bestimmten Stellen. Das Programm sollte 32 Hexadezimalziffern (128 Bit) in Form von xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx( 8-4-4-4-12Ziffern) ausgeben , wobei xes sich um eine zufällige Hexadezimalzahl handelt. Vorausgesetzt, das PRNG Ihrer Sprache ist perfekt, müssen alle gültigen Ausgaben die gleiche Wahrscheinlichkeit haben, generiert zu werden.

TL; DR

Generieren Sie 32 zufällige hexadezimale Ziffern in den Formularziffern 8-4-4-4-12. Kürzester Code gewinnt.

EDIT: Muss hexadezimal sein. Es ist ungültig, immer nur eine Dezimalzahl zu generieren. EDIT 2: Keine eingebauten. Dies sind keine GUIDs, nur generische Hex-Ziffern.


Beispielausgabe:

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

Eingabe- und Standardlücken sind nicht zulässig.


Das ist , also gewinnt der kürzeste Code. Fragen Sie auch gerne nach.


5
Scheint wie eine weniger strenge Version von codegolf.stackexchange.com/q/32309/14215
Geobits

9
"Diese Beispiele sind nicht zufällig. Versuchen Sie, eine Bedeutung beizumessen." Was bedeutet das?
Alex A.

3
Eigentlich braucht man keine Hexadezimalzahlen, 10-Basen können auch zufällig sein. Sollte beispielsweise 12345678-1234-1234-1234-123456789012eine gültige UUID sein (oder ist eine Hex-Ziffer erforderlich?). Halten Sie das für eine Lücke?
Voitcus

3
Der Titel und der erste Satz deuten darauf hin, dass Sie eine kanonische UUID wünschen, und die angegebenen Beispiele scheinen der Spezifikation für UUIDs zu entsprechen, aber Sie scheinen tatsächlich nach etwas anderem zu fragen.
Peter Taylor

3
Ich fühle mich gezwungen, darauf hinzuweisen, dass die (zufällige) UUID der Version 4 ein erforderliches Format hat, von xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx dem yeines stammt [89AB]. Zum Zeitpunkt dieses Kommentars wird garantiert, dass keine der Antworten (mit Ausnahme von C # unter Verwendung einer eingebauten Bibliothek) eine gültige zufällige UUID erzeugt (und es ist sehr wahrscheinlich, dass tatsächlich keine erzeugt wird).

Antworten:


11

Pyth, 20 Bytes

j\-msm.HO16*4hdj83 3

Demonstration.

Codiert [1, 0, 0, 0, 2]als 83 in Basis 3, addiert dann eins und multipliziert mit vier, um die Länge jedes Segments zu erhalten. Dann werden hexadezimale Ziffern und Bindestriche hinzugefügt.


8

Julia, 80 Bytes

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

Generieren Sie eine zufällige 128-Bit-Ganzzahl, erhalten Sie ihre hexadezimale Darstellung als Zeichenfolge, die mit 32 Ziffern aufgefüllt ist, und unterteilen Sie diese in Segmente, die durch Bindestriche verbunden sind.

Vielen Dank an ConfusedMr_C und kvill für ihre Hilfe!


8

CJam, 26 25 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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 Byte

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

bearbeiten: fremde Eltern:

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

edit: konnte das nachfolgende .Trim ("-") aus dem Original entfernen:

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

Je nach Art der Flags (-f und -Join) kann es mit Leerzeichen klarer sein. Ich möchte immer noch den letzten Trim ("-") verlieren:

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

Oder mit der eingebauten Funktionalität (ua die obige C # -Antwort)

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

Es scheint jedoch eine kleine Abkürzung zu sein, selbst wenn es bei 31 Bytes ankommt.


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

5

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

Diese Verkettung von Zeichenfolgenformatierungen bewirkt, dass Python die Hexadezimalzahlen für jedes Segment eindeutig formatiert.

Ungolfed:

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

Dies könnte eine Verbesserung gebrauchen, aber ich bin stolz.



4

PHP, 69 72 75 Bytes

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

Dies gibt keine hexadezimalen Ziffern ( a, ... f) aus. Sie sind erlaubt, aber vom Fragetext nicht verlangt.

Keine Zifferngruppe beginnt mit 0(auch nicht erforderlich).

edit: 3 Bytes gespart dank @IsmaelMiguel


Das sieht aus wie ein Bi mehr als 32 Bytes.
isaacg,

@isaacg ja, sorry - mein Fehler
Voitcus

Sie sollten join()stattdessen verwenden.
Ismael Miguel

3

C #, 65 Bytes

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

bearbeiten: Ja! C # ist kürzer als eine andere Sprache (außer Java) :)


1
Ich denke, dies wird als Standardlücke angesehen ... :( meta.codegolf.stackexchange.com/questions/1061/…
Dom Hastings

1
Ich denke, dies wird nicht als Standardlücke angesehen: Wie Sie sehen können, hat die Aufforderung, dieses Zeug aufzugeben, in über 1 Jahr nur 2 positive Stimmen erhalten. Im Gegensatz dazu erhielt der Kommentar, der besagt, dass Sie eingebaute Funktionen verwenden sollten, 58 positive Stimmen. Oder wie ein Kommentator sagte -> Wenn wir uns alle auf die gleichen integrierten Funktionen beschränken würden, würde jeder Wettbewerb von APL oder Golfscript gewonnen, da deren Befehlsnamen die kürzesten sind. (Michael Stern)
Stephan Schinkel

1
oder anders ausgedrückt: Können wir printf verwenden? Oder sollten wir Inline-Asm verwenden, um Interrupt 21 auszulösen?
Stephan Schinkel

Ein guter Punkt! Ich wollte mich nicht aufregen, ich wollte nur hilfreich sein! Dann könnte Mathematica gewinnen CreateUUID[]!
Dom Hastings

1
@StephanSchinkel Die "nur 2 positiven Stimmen in einem Jahr" sind irreführend. Es hat derzeit 47 Upvotes und 45 Downvotes, also netto +2. Abgesehen davon ist die allgemein akzeptierte Schwelle höher als diese, und Sie haben Recht, dass sie derzeit nicht wirklich als Standardlücke gilt.
Geobits,

3

Gawk, 86

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

Sie können dies einmal pro Sekunde verwenden, um eine eindeutige zufällige "UUID" zu generieren. Dies liegt daran, dass srand()die Systemzeit in Sekunden seit der Epoche als Argument verwendet wird, wenn kein Argument angegeben ist.

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

Ich finde den awk-Teil ziemlich elegant.

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

Wenn Sie es öfter als einmal pro Sekunde verwenden möchten, können Sie es in bash wie folgt aufrufen. Beachten Sie, dass auch der awk-Teil geändert wird.

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

Das echowird dort hinzugefügt, um jedes Mal eine neue Zeile zu drucken.


3

K5, 35 Bytes

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

Um ein Hex-Alphabet zu generieren, generiere ich eine Zeichenkette ( `c$) aus einer Liste von Ziffern ( 48+!10) und den ersten 6 Großbuchstaben ( 65+!6). Eine alternative Methode zur Erzeugung von Ziffern gleicher Länge ist ,/$!10.

Mit der generierten Zeichenfolge "0123456789ABCDEF" ist der Rest einfach. Wählen Sie 32 zufällige Werte aus dieser Menge ( 32?) aus, schneiden Sie ( _) den resultierenden String bei der 0 8 12 16 20Berechnung über (0,8+4*!4)und verbinden Sie die resultierenden String-Fragmente mit Bindestrichen ( "-"/).

In Aktion:

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

3

R , 63 Bytes

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

Probieren Sie es online!

Der Code erstellt zuerst eine zufällige Zeichenfolge mit 36 ​​Zeichen und platziert dann die vier Bindestriche. Es gibt eine UUID an stdout aus.


Ersetzen Sie den cAnruf sprintf("%x",0:15)durch -1.
J.Doe

3

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

Verwendet Regex ersetzen. Behandelt die Formatzeichenfolge als Anzahl zum Generieren eines Hex-Zeichens. Heben wo ich kann; Wenn möglich, werden Semikolons weggelassen.


89 Bytes'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 Bytes

Das Offensichtliche:

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

Das Übersetzen des Perl 5-Beispiels mit printfergibt einen etwas kürzeren Code.

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

(0..16⁴)?! Kann man das in Perl machen?
klatschen

1
@VoteToSpam Du kannst ab vor 9 Tagen . (Perl 6 wird später in diesem Monat veröffentlicht)
Brad Gilbert b2gills

Cooooool. Vielleicht sollte ich es lernen
klatsche

@VoteToSpam Das ist nichts im Vergleich zu 1,2,4,8,16 ... *dem , was eine faule unendliche Liste der Potenzen von 2 erzeugt ( {2**$++} ... *funktioniert auch)
Brad Gilbert b2gills


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

Probieren Sie es online!

Dies ist meine erste APL-Einreichung. Ein großes Dankeschön an @ Adám für das Gespräch mit mir im APL-Chat des PPCG und für die hexadezimale Konvertierungsfunktion.

Vielen Dank an @ Zacharý für 1 Byte

Bearbeitet, um die Anzahl der Bytes zu korrigieren.


Sie können davon ausgehen ⎕IO←0, dass dies keine Byte-Kosten verursacht. Außerdem können die meisten Bytes (IIRC, alle hier vorhandenen) in APL als eins gezählt werden.
Zacharý

@ Zacharý Ich habe TIO verwendet, um die Bytes für meine Übermittlung zu zählen. Hätte ich stattdessen die Anzahl der Zeichen verwenden sollen? Ich bin noch neu in PPCG und benutze APL, daher weiß ich nicht genau, wie ich die Byteanzahl dafür machen soll.
J. Sallé

Außerdem können Sie ändern , a(H 12?16)um a H 12?16ein Byte zu speichern.
Zacharý


2

Japt , 32 Bytes

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

Probieren Sie es online!


Willkommen bei PPCG und willkommen bei Japt :) Ich werde Ihre Lösungen bis jetzt durchgehen, wenn ich etwas Zeit habe (gerade aus dem Urlaub zurück, so viel zum Nachholen), aber der erste Tipp, den ich anbieten werde, ist, sich vertraut zu machen Um sich mit den Unicode-Verknüpfungen ( m@- £) vertraut zu machen und Ihnen den Einstieg zu erleichtern, finden Sie hier eine 24-Byte-Version Ihrer Lösung, die Sie in aller Eile herunterladen können:
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

Benötigt perl5> = 5.10 denke ich. Für den Modifizierer / r und für say ().


1
Nett! Das ist viel besser als meins! Nachdem bei Ihrer Lösung sieht, könnten Sie sogar in der Lage sein , mehr , basierend auf speichern dieser Meta Post mit s//xx-x-x-x-xxx/;s/x/sprintf"%04x",rand 65536/egmit -pFlagge, würde auch bedeuten , funktioniert sich auf ältere Versionen ohne -E.
Dom Hastings

Vielen Dank. Ihr Vorschlag lautet: echo | perl -pe's // xx-xxx-xxx /; s / x / sprintf "% 04x", rand 65536 / zB 'Und das sind nur 48 Zeichen zwischen' '. (Betrügt diese Art von? Vielleicht nicht)
Kjetil S.

Laut diesem Meta-Post ist es akzeptabel, ich hatte noch keine Gelegenheit, diesen Mechanismus selbst zu nutzen, aber ich hoffe, ich werde es bald genug tun! Wäre 49 Bytes (+ -p), aber immer noch ziemlich gut und ich hätte diesen Ansatz nicht in Betracht gezogen, ohne Ihre Antwort zu sehen!
Dom Hastings


1

C ++, 194 193 221 210 201 Bytes

+7 Bytes dank Zacharý (erkannt ein -, das nicht am Ende sein sollte)

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

Wenn jemand die Möglichkeit hat, bei jeder Ausführung einen anderen Wert zu erhalten, ohne ihn zu ändern srandund ohne ihn einzuschließen <ctime>, wäre das großartig


Kann nicht #define L(a) for... sein #define L(a)for...? (
Könnte

Dies ist ungültig, es gibt ein "-" am Ende (was nicht sein sollte)
Zacharý

@ Zacharý Korrektur beantragt jetzt
HatsuPointerKun


1
Könnten Sie so etwas tun "0123456789abcdef"[rand()%16]und dann entfernen f?
Zacharý


1

Bash, 67 Bytes

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

Willkommen bei PPCG!
Dennis

1

JavaScript REPL, 79 Bytes

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

Probieren Sie es online!

Math.randomkann zurückkehren 0. Addiert man 5 Nullen, erhält das Schneiden 4 0Sekunden


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 ;

Probieren Sie es online!

Erläuterung

Ändert die Basis in hexadezimal und gibt dann Zahlen / Segmente der entsprechenden Länge in festgelegten Intervallen mit Bindestrichen aus

Code-Erklärung

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

Probieren Sie es online!

Ich hätte diese Version gerne in einem Kommentar zu Max Yekhlakov ( seiner Antwort ) vorgeschlagen, aber leider habe ich noch nicht die 50 benötigten Reputationspunkte. Deshalb hier meine Antwort.

803912ist C4448in hexadezimal, beschreibt es , wie sollte die Ausgabe (formatiert werden 12-4-4-4-8), ist es umgekehrt ist , weil am wenigsten signifikanten Stellen zuerst gelesen werden.
 

Bearbeitungen:

  • 3 Bytes gespart dank Jonathan Frech
  • sparte 5 weitere Bytes durch Ersetzen srand(time(0))durchsrand(&i)

1
main(){...;int i=kann sein main(i){...;i=.
Jonathan Frech

Ich habe über etwas nachgedacht und anscheinend a als Ausgangsparameter srand()akzeptiert unsigned int. In tio.run unsigned intist an 4 Byte lang, aber die UUID ist 16 Byte lang. Dies bedeutet, dass nur ein winziger Bruchteil der gültigen Ausgaben (1/2 ^ 12) generiert wird, daher ist meine Lösung (wie auch die vorherige mit time(0)) nicht gültig. Was denkst du ?
Annyo

Die OP Staaten Assuming that your language's PRNG is perfect, all valid outputs must have the same probability of being generated.. Die Seed-Entropie bestimmt nicht notwendigerweise die RNG-Entropie, obwohl dies wahrscheinlich der Fall ist (hat die srand()Implementierung nicht überprüft ). Allerdings srand()ist mein Wissen ziemlich einheitlich, so dass , wenn die RNG war perfekt, es noch einheitlich sein würde. Ich denke daher, dass Ihre Antwort gültig ist.
Jonathan Frech

OK ich verstehe. Ich könnte meine Antwort auch als Funktion einreichen, sofern dies srand()bereits geschehen ist, und in diesem Fall wird es keinen Zweifel geben. Aber ich bin nicht sicher, ob dies erlaubt ist, andere C / C ++ - Einreichungen scheinen alle srand()int die Antwort zu enthalten (es sei denn, es wird nicht verwendet rand())
Annyo


1

C (gcc) 143 110 103 96 94 Bytes

Dank Ceilingcat und Jonathan Frech auf 94 Bytes reduziert.

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

Probieren Sie es online!

Erläuterung:

/*
  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
Hallo und willkommen bei PPCG! 110 Bytes .
Jonathan Frech

@ JonathanFrech Vielen Dank! Ihre Version ist sehr beeindruckend!
Max Yekhlakov

Schlagen Sie *z=L"\27\23\17\vz"anstelle von *z=L"\10\4\4\4\14"und for(n=32;n--;z+=printf("-%x"+(n!=*z),P()&15)-1)anstelle von vorfor(;*z;*++z&&putchar(45))for(n=*z;n--;printf("%x",P()&15))
ceilingcat

1

Java mit zehn Fuß 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)));}

Getestet mit Version 1.06 der Bibliothek, dies sollte jedoch mit jeder Version 1.04 oder neuer funktionieren.



0

SmileBASIC, 65 62 Bytes

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

Ich habe eine Funktion 4 zufällige hexadezimale Ziffern drucken: DEF H?HEX$(RND(65536),4);:ENDsowie 4 Stellen mit einem -nach ihnen DEF G:H?"-";:END. Dann muss es diese Funktionen nur ein paar Mal aufrufen.


0

Chip , 109 + 6 = 115 Bytes

Benötigt Flags -wc36, die +6 Bytes verursachen

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

Probieren Sie es online!

Erzeugt 4 zufällige Bits (die vier ?) und wandelt sie in hexadezimale Ziffern um:

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

... ein bisschen unkonventionell, aber es hat mir ein paar Bytes erspart, und zwar ohne Kosten für die Verteilung der Ergebnisse.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.