Einfacher Beweis, dass die GUID nicht eindeutig ist [geschlossen]


323

Ich möchte beweisen, dass eine GUID in einem einfachen Testprogramm nicht eindeutig ist. Ich habe erwartet, dass der folgende Code stundenlang ausgeführt wird, aber er funktioniert nicht. Wie kann ich es zum Laufen bringen?

BigInteger begin = new BigInteger((long)0);
BigInteger end = new BigInteger("340282366920938463463374607431768211456",10);  //2^128
for(begin; begin<end; begin++)
  Console.WriteLine(System.Guid.NewGuid().ToString());

Ich benutze C #.


107
Was würden Sie als Softwareentwickler sagen, wenn ein Benutzer zu Ihnen käme und sagte, dass es nicht funktioniert?
JoshJordan

152
Warten Sie mehrere Billionen Jahre.
Hobbs

67
Upmodded, weil dies das amüsanteste ist, was ich heute online gesehen habe.
Jrockway

32
@ Rockway - lol. Ich habe Probleme, etwas über diese Frage zu finden, das nicht grundsätzlich falsch ist. Je länger ich es mir anschaue, desto lustiger wird es.
Tyler

243
Es ist nur global einzigartig, also nur auf unserem Planeten. Wenn Sie eine wirklich eindeutige ID wünschen, müssen Sie eine universell eindeutige ID (UUID) verwenden. Ich gehe davon aus, dass Sie nur an der Einzigartigkeit in unserem Universum interessiert sind. :-)
Tvanfosson

Antworten:


407

Kai, ich habe ein Programm bereitgestellt, das mithilfe von Threads macht, was Sie wollen. Es ist unter den folgenden Bedingungen lizenziert: Sie müssen mir 0,0001 USD pro Stunde und CPU-Kern zahlen, auf dem Sie es ausführen. Die Gebühren sind am Ende eines jeden Kalendermonats zu zahlen. Bitte kontaktieren Sie mich so schnell wie möglich, um meine Paypal-Kontodaten zu erhalten.

using System;
using System.Collections.Generic;
using System.Linq;

namespace GuidCollisionDetector
{
    class Program
    {
        static void Main(string[] args)
        {
            //var reserveSomeRam = new byte[1024 * 1024 * 100];     // This indeed has no effect.

            Console.WriteLine("{0:u} - Building a bigHeapOGuids.", DateTime.Now);
            // Fill up memory with guids.
            var bigHeapOGuids = new HashSet<Guid>();
            try
            {
                do
                {
                    bigHeapOGuids.Add(Guid.NewGuid());
                } while (true);
            }
            catch (OutOfMemoryException)
            {
                // Release the ram we allocated up front.
                // Actually, these are pointless too.
                //GC.KeepAlive(reserveSomeRam);
                //GC.Collect();
            }
            Console.WriteLine("{0:u} - Built bigHeapOGuids, contains {1} of them.", DateTime.Now, bigHeapOGuids.LongCount());


            // Spool up some threads to keep checking if there's a match.
            // Keep running until the heat death of the universe.
            for (long k = 0; k < Int64.MaxValue; k++)
            {
                for (long j = 0; j < Int64.MaxValue; j++)
                {
                    Console.WriteLine("{0:u} - Looking for collisions with {1} thread(s)....", DateTime.Now, Environment.ProcessorCount);
                    System.Threading.Tasks.Parallel.For(0, Int32.MaxValue, (i) =>
                    {
                        if (bigHeapOGuids.Contains(Guid.NewGuid()))
                            throw new ApplicationException("Guids collided! Oh my gosh!");
                    }
                    );
                    Console.WriteLine("{0:u} - That was another {1} attempts without a collision.", DateTime.Now, ((long)Int32.MaxValue) * Environment.ProcessorCount);
                }
            }
            Console.WriteLine("Umm... why hasn't the universe ended yet?");
        }
    }
}

PS: Ich wollte die Bibliothek für parallele Erweiterungen ausprobieren. Das war einfach.

Und die Verwendung von OutOfMemoryException als Kontrollfluss fühlt sich einfach falsch an.

BEARBEITEN

Nun, es scheint, dass dies immer noch Stimmen anzieht. Also habe ich das Problem mit GC.KeepAlive () behoben. Und es wurde geändert, um mit C # 4 zu laufen.

Und um meine Supportbedingungen zu verdeutlichen: Support ist nur am 28. Februar 2010 verfügbar. Bitte verwenden Sie eine Zeitmaschine, um Supportanfragen nur an diesem Tag zu stellen.

BEARBEITEN 2 Wie immer macht der GC einen besseren Job als ich beim Verwalten des Speichers; Alle früheren Versuche, es selbst zu tun, waren zum Scheitern verurteilt.


120
Diese letzte Console.WriteLine brachte mich zum Lachen. Ich denke du solltest CommonlyAcceptedCosmologicTheoriesWrongExceptionstattdessen einen werfen .
R. Martinho Fernandes

17
Bedeutet das Markieren als Akzeptiert auch, dass @Kai die von @ligos festgelegten Bedingungen akzeptiert?
kb.

3
Das Einstellen reserveSomeRam = null;bringt eigentlich nichts.
DevinB

4
@devinb bitte erklären? Es sieht so aus, als würde es die zuvor zugewiesenen Bytes freigeben, damit der GC es kann Collect(). Warum erreicht es nichts?
Mythos

3
GuidCollisionDetector. Der Name hat Potenzial
Ufuk Hacıoğulları

226

Dies wird viel mehr als Stunden dauern. Angenommen, es schleift mit 1 GHz (was nicht der Fall ist - es wird viel langsamer als das sein), läuft es 10790283070806014188970 Jahre. Das ist ungefähr 83 Milliarden Mal länger als das Alter des Universums.

Unter der Annahme, dass das Moores-Gesetz gilt, wäre es viel schneller, dieses Programm nicht auszuführen, mehrere hundert Jahre zu warten und es auf einem milliardenfach schnelleren Computer auszuführen. Tatsächlich wird jedes Programm, dessen Ausführung länger dauert als die Verdoppelung der CPU-Geschwindigkeit (ca. 18 Monate), früher abgeschlossen, wenn Sie warten, bis sich die CPU-Geschwindigkeit erhöht hat, und eine neue CPU kaufen, bevor Sie es ausführen (es sei denn, Sie schreiben es so, dass es kann auf neuer Hardware angehalten und fortgesetzt werden).


27
Verdammt - vielleicht ist es eine bessere Idee, mehrere Threads zu erstellen, die Guids generieren?
Kai

107
4 Threads auf einem Quad-Core-Prozessor würden ihn im 20-Milliarden-fachen Alter des Universums laufen lassen - also ja, das würde viel helfen.
rjmunro

34
Ich bin misstrauisch, dass dies ein Troll ist, aber mit der Möglichkeit, dass dies nicht der Fall ist: Fäden sind nicht magisch. Wenn Sie eine Milliarde Operationen pro Sekunde mit einem Thread ausführen können, bedeutet das Wechseln zu zehn Threads, dass jeder 1/10 so oft ausgeführt wird. Jeder Thread führt 100 M Operationen pro Sekunde aus. Die Gesamtzahl der Vorgänge pro Sekunde wird nicht erhöht. Um die Anzahl der Vorgänge pro Sekunde zu erhöhen, müssen Sie mehr Computer kaufen. Angenommen, Sie haben eine Milliarde weitere Computer gekauft. Dies würde das Problem auf nur 10790283070806 Jahre reduzieren, was immer noch mehr als vier Stunden sind.
Eric Lippert

10
Ich denke, rjmunro geht davon aus, dass jeder Thread auf einem separaten Kern ausgeführt wird. 83 Milliarden Universen / 4 Kerne entsprechen in der Tat ungefähr 20 Milliarden Universen. Zeit, Intel-Aktien zu kaufen!
Dour High Arch

4
@Erik 83 Milliarden Prozessoren bedeuten, dass Sie dies in ungefähr der Zeit tun können, in der das Universum bisher existiert hat. Selbst das ist bei weitem nicht genug.
rjmunro

170

Eine GUID ist theoretisch nicht eindeutig. Hier ist dein Beweis:

  • GUID ist eine 128-Bit-Zahl
  • Sie können nicht 2 ^ 128 + 1 oder mehr GUIDs generieren, ohne alte GUIDs erneut zu verwenden

Wenn jedoch die gesamte Leistung der Sonne auf diese Aufgabe gerichtet wäre, würde es lange vor dem Ende kalt werden.

GUIDs können mit einer Reihe verschiedener Taktiken generiert werden, von denen einige spezielle Maßnahmen ergreifen, um sicherzustellen, dass eine bestimmte Maschine nicht zweimal dieselbe GUID generiert. Das Auffinden von Kollisionen in einem bestimmten Algorithmus würde zeigen, dass Ihre bestimmte Methode zum Generieren von GUIDs schlecht ist, würde jedoch nichts über GUIDs im Allgemeinen beweisen.


44
Pigeonhole Prinzip zur Rettung!
Yfeldblum

22
+1 für die Sonne wird kalt Kommentar. Irgendwo gab es einen interessanten Kommentar zur Sinnlosigkeit von Verschlüsselungsschlüsseln> 256 Bit. Das Durchlaufen aller möglichen Schlüsselwerte würde mehr Energie erfordern, als das gesamte Universum enthält. Ein bisschen in der CPU umzuschalten erfordert eine kleine Energiemenge (es ist das, was die Wärme erzeugt), die, wenn sie 2 ^ 256-mal multipliziert wird, eine wirklich massive Zahl ist, die die im Universum gespeicherte Energie übersteigt, wobei E = mc2 verwendet wird, für das das Universum Masse benötigen würde 2 ^ 227kg, unsere Sonne ist 2 ^ 101kg, das sind also 2 ^ 126 Sonnen!
Skizz

31
@ Skizz: Dies gilt nur für Brute-Force-Angriffe. Wenn ein Verschlüsselungsschema "kaputt" ist, bedeutet dies, dass es in kürzerer Zeit als Brute Force gelöst werden kann, die Lösungszeit jedoch proportional zur Schlüsselgröße bleibt.
Steven Sudit

1
@StevenSudit: proportional zum Exponenten der Schlüsselgröße (außer P == NP)
Ihar Bury

1
@Orlangur Proportional zur in Bits gemessenen Schlüsselgröße.
Steven Sudit

137

Natürlich können GUIDs kollidieren. Da GUIDs 128-Bit sind, generieren Sie 2^128 + 1sie einfach und nach dem Pigeonhole-Prinzip muss es zu einer Kollision kommen.

Wenn wir jedoch sagen, dass eine GUID einzigartig ist, meinen wir wirklich, dass der Schlüsselraum so groß ist, dass es praktisch unmöglich ist, dieselbe GUID versehentlich zweimal zu generieren (vorausgesetzt, wir generieren GUIDs zufällig).

Wenn Sie eine Folge von nGUIDs zufällig generieren , ist die Wahrscheinlichkeit für mindestens eine Kollision ungefähr p(n) = 1 - exp(-n^2 / 2 * 2^128)(dies ist das Geburtstagsproblem mit der Anzahl möglicher Geburtstage 2^128).

   n     p(n)
2^30 1.69e-21
2^40 1.77e-15
2^50 1.86e-10
2^60 1.95e-03

Um diese Zahlen konkret zu machen , 2^60 = 1.15e+18. Wenn Sie also eine Milliarde GUIDs pro Sekunde generieren, 2^60benötigen Sie 36 Jahre, um zufällige GUIDs zu generieren, und selbst dann ist die Wahrscheinlichkeit, dass Sie eine Kollision haben, immer noch 1.95e-03. Es ist wahrscheinlicher, dass Sie irgendwann in Ihrem Leben ermordet werden ( 4.76e-03), als dass Sie in den nächsten 36 Jahren eine Kollision finden. Viel Glück.


239
Wenn Sie irgendwann in Ihrem Leben ermordet werden, ist es wahrscheinlich am Ende.
Michael Myers

25
@mmyers: Ausgezeichneter Punkt. Das bedeutet, dass meine Chancen, gerade ermordet zu werden, absurd gering sind, da dies nicht das Ende meines Lebens ist. Oh, warte ...
Steven Sudit

Wenn innerhalb kurzer Zeit zwei GUIDs erstellt werden, ist die Wahrscheinlichkeit gering, dass sie im selben System verwendet werden. Dies erhöht daher die Einzigartigkeit.
AMissico

Diese Zahlen und Verweise auf das Geburtstagsproblem sind bedeutungslos. GUID-Generierungsalgorithmen generieren nicht mit gleicher Wahrscheinlichkeit Werte über den gesamten Bereich. Tatsächlich verwendete der ursprüngliche Algorithmus IIRC die MAC-Adresse des generierenden PCs + die aktuelle Zeit als Teil des Ergebnisses - was das Risiko einer Kollision mit auf anderen PCs generierten Guids verringert, aber natürlich den Schlüsselraum verringert.
Joe

17
Sie gehen davon aus, dass die Wahrscheinlichkeit, ermordet zu werden, für alle Menschen eine Konstante ist. Aber eindeutig sind Menschen, die in Forenbeiträgen abfällige Bemerkungen schreiben, die Art von Menschen, die mit größerer Wahrscheinlichkeit ermordet werden als die durchschnittliche Person.
Jay

61

Wenn Sie sich Sorgen um die Einzigartigkeit machen, können Sie jederzeit neue GUIDs kaufen, um Ihre alten wegzuwerfen. Ich werde einige bei eBay einstellen, wenn Sie möchten.


13
Cool - wie viel für den kompletten Satz von 0 bis (2 ^ 128) -1?
Steve314

23
Zum Verkauf: 0,01 USD pro 1.000 GUIDs. Ich werde ein paar Bambuswindspiele einwerfen, wenn Sie in den nächsten 60 Minuten bestellen.
ctacke

7
Mein Set ist exklusiver und von höherer Qualität. Sie werden doppelt geprüft und verifiziert, wodurch sie den Wert von 1 USD pro GUID wert sind. Sie können sie sogar in Chargen kaufen, wenn Sie nicht die volle Investition auf einmal tätigen möchten. Ich muss jedoch zusätzliche 10 USD pro Charge berechnen.
Thomas

3
Ich werde Ihnen einen monatlichen Plan aufstellen und Ihnen unbegrenzte Anleitungen zum richtigen Preis geben. ^ Diese Leute versuchen dich zu betrügen und dir überteuerte Guids zu verkaufen. Ich verkaufe Ihnen hochwertige Guids made in China!
ErocM

47

Persönlich denke ich, dass der "Urknall" verursacht wurde, als zwei GUIDs kollidierten.


4
Denken

Ich würde gerne Ihre Argumentation zu Ihrer Theorie hören. Ich denke, wir könnten auf dieser Grundlage eine neue Religion gründen und T.Cruise rekrutieren!
ErocM

@ErocM; Siehe "Brane-Kosmologie" ( en.wikipedia.org/wiki/Brane_cosmology ) und "Membran (M-Theorie)" ( en.wikipedia.org/wiki/Membrane_(M-Theory) ). Die Idee ist, wenn zwei Branes ein neues Universum berühren, entsteht es. Daher können Sie daraus schließen, dass ein neues Universum entsteht, wenn sich zwei GUIDs berühren.
AMissico

2
Wenn Timecop uns etwas gelehrt hat, ist es, dass dieselbe Materie zu einem bestimmten Zeitpunkt nicht denselben Raum einnehmen kann. Wenn also zwei GUIDs kollidieren würden, würden sie sich gegenseitig verbrauchen und die daraus resultierende Implosion würde ein Schwarzes Loch erzeugen, das das gesamte Universum verschlingt. In Wirklichkeit würde es also kein Universum erschaffen, es würde es zerstören.
AJC

42

Sie können dies in O (1) -Zeit mit einer Variante des Quanten-Bogosort- Algorithmus zeigen.

Guid g1 = Guid.NewGuid();
Guid g2 = Guid.NewGuid();
if(g1 != g2) Universe.Current.Destroy();

21
Ich erhalte eine Ausnahme, wenn ich Destroy () aufrufe. Basierend auf dem Text denke ich, dass meinem Computer die notwendige Hardware fehlt, um das aktuelle Universum zu zerstören. Wissen Sie, wo ich es bekommen kann?
Steven Sudit

11
@Steven: Nein, einige Manager waren zu besorgt darüber, wie schlecht diese API für die Öffentlichkeit aussehen würde, und diktierten, dass sie aus "Sicherheitsgründen" immer fehlschlagen sollte. Wenn Sie sich die Quelle der Methode ansehen, gibt es nur diese eine Zeile : throw new MundaneHardwareException();. Wie auch immer, ich habe gehört, die Jungs am CERN haben eine Art Big Hadron Thingy, das den Trick machen könnte ...
R. Martinho Fernandes

7
@ Martininho: Ah, ok. Ich werde in Ersatz aussehen Universe.Current.Destroy()mit Cern.Lhc.DestroyThisUniverse().
Steven Sudit

61
Ich wusste, dass es einen Grund gab, warum ich in Haskell programmiert habe. Diese Nebenwirkungen werden unheimlich.
Edward KMETT

6
"Es gibt eine Theorie, die besagt, dass wenn jemand jemals genau entdeckt, wofür das Universum ist und warum es hier ist, es sofort verschwindet und durch etwas noch bizarrer Unerklärliches ersetzt wird. Es gibt eine andere Theorie, die besagt, dass dies bereits geschehen ist . " - Douglas Adams, Per Anhalter durch die Galaxis
Mike Pirnat

28

Zwei beliebige GUIDs sind sehr wahrscheinlich eindeutig (nicht gleich).

Siehe diesen SO-Eintrag und aus Wikipedia

Während nicht garantiert wird, dass jede generierte GUID eindeutig ist, ist die Gesamtzahl der eindeutigen Schlüssel (2 ^ 128 oder 3,4 × 10 ^ 38) so groß, dass die Wahrscheinlichkeit, dass dieselbe Nummer zweimal generiert wird, sehr gering ist. Betrachten Sie zum Beispiel das beobachtbare Universum, das etwa 5 × 10 ^ 22 Sterne enthält. Jeder Stern könnte dann 6,8 × 10 ^ 15 universell eindeutige GUIDs haben.

Wahrscheinlich müssen Sie noch viele Milliarden Jahre warten und hoffen, dass Sie einen vor dem Universum treffen, wie wir wissen, dass es zu Ende geht.


Ist 2 ^ 128 also nicht die richtige Anzahl möglicher Guids?
Kai

21
Es ist. Warum denkst du, ist 2 ^ 128 eine kleine Zahl?
Jrockway

Ja, 2 ^ 128 ist die richtige Anzahl möglicher Guids.
Graviton

3
Das ist eine verdammt große Zahl. $ irb >> 2**128 => 340282366920938463463374607431768211456
AdamJLev

45
@Infinity - Auch für dich?
Austin Richardson

27

[Aktualisieren:] Wie die folgenden Kommentare zeigen, sind neuere MS-GUIDs V4 und verwenden die MAC-Adresse nicht als Teil der GUID-Generierung (ich habe jedoch keinen Hinweis auf eine V5-Implementierung von MS gesehen, wenn also jemand eine hat Link zur Bestätigung, lassen Sie es mich wissen). Mit V4 spielt die Zeit jedoch immer noch eine Rolle, und die Wahrscheinlichkeit, dass GUIDs doppelt vorhanden sind, bleibt so gering, dass sie für den praktischen Gebrauch irrelevant sind. Es ist sicher unwahrscheinlich, dass Sie jemals eine doppelte GUID aus nur einem einzigen Systemtest generieren, wie es das OP versucht hat.

Den meisten dieser Antworten fehlt ein wichtiger Punkt bei der GUID-Implementierung von Microsoft. Der erste Teil der GUID basiert auf einem Zeitstempel und ein anderer Teil basiert auf der MAC-Adresse der Netzwerkkarte (oder einer Zufallszahl, wenn keine Netzwerkkarte installiert ist).

Wenn ich das richtig verstehe, bedeutet dies, dass die einzige zuverlässige Möglichkeit zum Duplizieren einer GUID darin besteht, gleichzeitige GUID-Generierungen auf mehreren Computern auszuführen, auf denen die MAC-Adressen identisch waren UND auf denen die Uhren auf beiden Systemen genau zum Zeitpunkt der Generierung waren aufgetreten (der Zeitstempel basiert auf Millisekunden, wenn ich ihn richtig verstehe) .... selbst dann gibt es viele andere Bits in der Zahl, die zufällig sind, so dass die Chancen immer noch verschwindend gering sind.

Für alle praktischen Zwecke sind die GUIDs universell einzigartig.

Es gibt eine ziemlich gute Beschreibung der MS GUID im Blog "The Old New Thing"


3
Das ist tatsächlich machbar, wenn Virtualisierung verwendet wird. Sie können und Sie erhalten doppelte Anleitungen.
Goran

8
Raymond ist im MAC-Adressenteil veraltet, Microsoft verwendet diese jedoch nicht mehr. Siehe en.wikipedia.org/wiki/GUID#Algorithm für den Unterschied zwischen V1- und V4-Guids.
Michael Stum

1
Dies ist nicht mehr der Fall. Das aktuelle V5-Schema besteht nur aus 128 Bit reiner Pseudozufallsgüte.
Edward KMETT

lustig, wie du alles sagst, was ich einen Monat später als ich getan habe und du 16 Punkte bekommst und ich immer noch 0 habe?
Anthony Lambert

1
Ya Tony, daran ist etwas Seltsames. Als ich den Beitrag beantwortete, gab es nur 3 oder 4 Antworten, und ich konnte mich nicht erinnern, Ihre gesehen zu haben ... wenn ich das getan hätte, hätte ich sie einfach positiv bewertet. Normalerweise beantworte ich keine Fragen, wenn es bereits andere Antworten gibt, die dies gut genug abdecken (weshalb ich wahrscheinlich eine relativ niedrige Gesamtwiederholung habe).
Stephen M. Redd

23

Hier ist eine raffinierte kleine Erweiterungsmethode, die Sie verwenden können, wenn Sie die Eindeutigkeit von Guid an vielen Stellen in Ihrem Code überprüfen möchten.

internal static class GuidExt
{
    public static bool IsUnique(this Guid guid)
    {
        while (guid != Guid.NewGuid())
        { }
        return false;
    }
}

Um es aufzurufen, rufen Sie einfach Guid.IsUnique auf, wenn Sie eine neue Guid generieren ...

Guid g = Guid.NewGuid();
if (!g.IsUnique())
{
    throw new GuidIsNotUniqueException();
}

Ich würde sogar empfehlen, es zweimal anzurufen, um sicherzustellen, dass es in der ersten Runde richtig lief.


2
Wie stellt dies sicher, dass this guidnirgendwo sonst auf dieser Welt etwas erzeugt wurde? : p Heck wir brauchen einen World Guid Pool. :)
Nawfal

19

Zählen bis 2 ^ 128 - ehrgeizig.

Stellen wir uns vor, wir können 2 ^ 32 IDs pro Sekunde und Maschine zählen - nicht das ehrgeizig, da es nicht einmal 4,3 Milliarden pro Sekunde sind. Widmen wir dieser Aufgabe 2 ^ 32 Maschinen. Lassen Sie uns außerdem 2 ^ 32 Zivilisationen dazu bringen, jeweils die gleichen Ressourcen für die Aufgabe bereitzustellen.

Bisher können wir 2 ^ 96 IDs pro Sekunde zählen, was bedeutet, dass wir 2 ^ 32 Sekunden (etwas mehr als 136 Jahre) zählen werden.

Jetzt brauchen wir nur noch 4.294.967.296 Zivilisationen für jede dedizierte 4.294.967.296 Maschine, wobei jede Maschine in den nächsten 136 Jahren 4.294.967.296 IDs pro Sekunde nur für diese Aufgabe zählen kann - ich schlage vor, wir beginnen jetzt mit dieser wesentlichen Aufgabe. -)


17

Wenn Sie die Laufzeit von 83 Milliarden Jahren nicht erschreckt, denken Sie, dass Sie die generierten GUIDs auch irgendwo speichern müssen, um zu überprüfen, ob Sie ein Duplikat haben. Wenn Sie 2 ^ 128 16-Byte-Nummern speichern, müssen Sie nur 4951760157141521099596496896 Terabyte RAM im Voraus zuweisen. Stellen Sie sich also vor, Sie haben einen Computer, der all das passt, und Sie finden irgendwie einen Ort, an dem Sie Terabyte-DIMMs mit jeweils 10 Gramm kaufen können Wiegen Sie mehr als 8 Erdmassen, damit Sie sie ernsthaft aus der aktuellen Umlaufbahn verschieben können, bevor Sie überhaupt auf "Ausführen" klicken. Denke nochmal nach!


12
for(begin; begin<end; begin)
    Console.WriteLine(System.Guid.NewGuid().ToString());

Sie erhöhen nicht, beginsodass die Bedingung begin < endimmer erfüllt ist.


1
nein - weil ich bigint nicht iterieren kann
Kai

3
Ist es wirklich wichtig, ob er sich für immer wiederholt oder 340282366920938463463374607431768211456 mal wiederholt?
Jay

3
also ... würdest du lieber 340282366920938463463374607431768211456 mal oder für immer geschlagen werden?!?!?
ErocM

eigentlich ist es das, was wirklich auf die Frage antwortet! und überhaupt keine Stimmen: p
nawfal


9

Vermutlich haben Sie Grund zu der Annahme, dass der Algorithmus zur Erzeugung von Guids keine wirklich zufälligen Zahlen erzeugt, sondern tatsächlich mit einer Periode << 2 ^ 128 fährt.

Beispiel: RFC4122-Methode zum Ableiten von GUIDs, mit der die Werte einiger Bits festgelegt werden.

Der Nachweis des Radfahrens hängt von der möglichen Größe des Zeitraums ab.

Für kleine Zeiträume kann die Hash-Tabelle des Hash (GUID) -> GUID mit Ersetzung bei Kollision, wenn die GUIDs nicht übereinstimmen (beenden, wenn dies der Fall ist), ein Ansatz sein. Erwägen Sie auch, den Austausch nur in einem zufälligen Bruchteil der Zeit durchzuführen.

Wenn die maximale Zeitspanne zwischen Kollisionen groß genug ist (und nicht im Voraus bekannt ist), ergibt eine Methode letztendlich nur eine Wahrscheinlichkeit, dass die Kollision gefunden wird, wenn sie existiert.

Beachten Sie, dass wenn die Methode zum Generieren von Guids uhrbasiert ist (siehe RFC), möglicherweise nicht festgestellt werden kann, ob Kollisionen vorliegen, da entweder (a) Sie nicht lange genug warten können, bis sich die Uhr dreht. oder (b) Sie können nicht genügend Guids innerhalb eines Takts anfordern, um eine Kollision zu erzwingen.

Alternativ können Sie möglicherweise eine statistische Beziehung zwischen den Bits in der Guid oder eine Korrelation der Bits zwischen Guids anzeigen. Eine solche Beziehung könnte es sehr wahrscheinlich machen, dass der Algorithmus fehlerhaft ist, ohne notwendigerweise eine tatsächliche Kollision finden zu können.

Wenn Sie nur beweisen möchten, dass Guids kollidieren können, ist natürlich ein mathematischer Beweis, kein Programm, die Antwort.


8

Ich verstehe nicht, warum niemand die Aktualisierung Ihrer Grafikkarte erwähnt hat ... Wenn Sie einen High-End-NVIDIA Quadro FX 4800 oder etwas anderes (192 CUDA-Kerne) hätten, würde dies sicherlich schneller gehen ...

Wenn Sie sich ein paar NVIDIA Qadro Plex 2200 S4 (mit jeweils 960 CUDA-Kernen) leisten könnten, wäre diese Berechnung natürlich wirklich gut schreien. Vielleicht wäre NVIDIA bereit, Ihnen ein paar für eine "Technologie-Demonstration" als PR-Stunt zu leihen?

Sicherlich würden sie Teil dieser historischen Berechnung sein wollen ...


hmmmm ..... ich könnte es bei der Arbeit auf unserem 10.000-Knoten-Raster ausführen.
Anthony Lambert

8

Aber müssen Sie sicher sein, dass Sie ein Duplikat haben, oder ist es Ihnen nur wichtig, ob es ein Duplikat geben kann ? Um sicherzugehen, dass Sie zwei Personen mit demselben Geburtstag haben, benötigen Sie 366 Personen (ohne Schaltjahr). Für eine Wahrscheinlichkeit von mehr als 50%, dass zwei Personen denselben Geburtstag haben, benötigen Sie nur 23 Personen. Das ist das Geburtstagsproblem .

Wenn Sie 32 Bit haben, benötigen Sie nur 77.163 Werte, um eine Wahrscheinlichkeit von mehr als 50% für ein Duplikat zu haben. Versuch es:

Random baseRandom = new Random(0);

int DuplicateIntegerTest(int interations)
{
    Random r = new Random(baseRandom.Next());
    int[] ints = new int[interations];
    for (int i = 0; i < ints.Length; i++)
    {
        ints[i] = r.Next();
    }
    Array.Sort(ints);
    for (int i = 1; i < ints.Length; i++)
    {
        if (ints[i] == ints[i - 1])
            return 1;
    }
    return 0;
}

void DoTest()
{
    baseRandom = new Random(0);
    int count = 0;
    int duplicates = 0;
    for (int i = 0; i < 1000; i++)
    {
        count++;
        duplicates += DuplicateIntegerTest(77163);
    }
    Console.WriteLine("{0} iterations had {1} with duplicates", count, duplicates);
}

1000 iterations had 737 with duplicates

Jetzt sind 128 Bit eine Menge, sodass Sie immer noch über eine große Anzahl von Elementen sprechen, die Ihnen immer noch eine geringe Kollisionswahrscheinlichkeit bieten. Sie würden die folgende Anzahl von Datensätzen für die angegebenen Quoten unter Verwendung einer Näherung benötigen:

  • 0,8 Milliarden Milliarden für eine 1/1000 Wahrscheinlichkeit einer Kollision
  • 21,7 Milliarden Milliarden für eine 50% ige Kollisionswahrscheinlichkeit
  • 39,6 Milliarden Milliarden für 90% Wahrscheinlichkeit einer Kollision

Es werden ungefähr 1E14-E-Mails pro Jahr gesendet, sodass es auf dieser Ebene ungefähr 400.000 Jahre dauern würde, bis Sie eine 90% ige Chance hätten, zwei mit derselben GUID zu erhalten. Dies unterscheidet sich jedoch erheblich von der Aussage, dass Sie einen Computer mit 83 Milliarden Euro betreiben müssen mal das Alter des Universums oder dass die Sonne kalt werden würde, bevor ein Duplikat gefunden wird.


7

Vermissen Sie nicht alle einen wichtigen Punkt?

Ich dachte, GUIDs wurden mit zwei Dingen generiert, die die Wahrscheinlichkeit, dass sie global einzigartig sind, sehr hoch machen. Zum einen werden sie mit der MAC-Adresse des Computers versehen, auf dem Sie sich befinden, und zum anderen verwenden sie die Zeit, zu der sie generiert wurden, plus eine Zufallszahl.

Wenn Sie es also nicht auf dem tatsächlichen Computer ausführen und alle Ihre Vermutungen innerhalb der kürzesten Zeit ausführen, die der Computer verwendet, um eine Zeit in der GUID darzustellen, werden Sie niemals dieselbe Zahl generieren, unabhängig davon, wie viele Vermutungen Sie mit dem Systemaufruf vornehmen.

Ich denke, wenn Sie wissen, wie eine GUID tatsächlich erstellt wird, würde sich die Zeit zum Erraten erheblich verkürzen.

Tony


3
Nicht alle GUIDs werden auf diese Weise erstellt. Selbst wenn dies der Fall wäre, muss Kai nur warten, bis der Zeitstempel, der zum Erstellen der GUID verwendet wurde, so oft umbrochen wird, bis einer, den er zum Erstellen einer GUID verwendet hat, erneut verwendet wird.
Dour High Arch

3
Guids basieren seit 2000 oder 2001 nicht mehr auf der Mac-Adresse. Ab einem der Service Packs für NT4 und / oder Win2k haben sie den Algorithmus insgesamt geändert. Sie werden jetzt von einem Zufallszahlengenerator generiert, abzüglich einiger Bits, die angeben, um welche Art von Guid es sich handelt.
KristoferA

4
Nicht alle GUIDs stammen von Windows-Plattformen ...
AnthonyLambert

OP erwähnt C #, also ist es Windows. Sind V4-GUIDs nur für Windows verfügbar?
Steven Sudit

5
@Martinho: Ah, aber Monos Unit-Test für Guid in GuidTest.cs enthält eine Methode, mit der zwei neue GUIDs erstellt und auf Gleichheit überprüft werden. Wenn sie gleich sind, schlägt dies fehl. Da Mono erfolgreich erstellt, können wir absolut sicher sein, dass seine GUIDs einzigartig sind! :-)
Steven Sudit

6

Sie könnten die GUIDs hashen. Auf diese Weise sollten Sie viel schneller ein Ergebnis erzielen.

Natürlich ist es auch eine gute Idee, mehrere Threads gleichzeitig auszuführen. Auf diese Weise erhöhen Sie die Wahrscheinlichkeit, dass eine Race-Bedingung dieselbe GUID zweimal auf verschiedenen Threads generiert.


6

GUIDs sind 124 Bit, da 4 Bit die Versionsnummer enthalten.


Der Grund, dies nicht als Kommentar hinzuzufügen: Niemand hat es erwähnt, und ich weiß nicht, wem ich das sagen soll. :)
Behrooz

Hooooraaaay ich habe es getan. In einer "echten" App, die ich geschrieben habe, habe ich eine Guid-Kollision in einer Tabelle mit ~ 260k Zeilen bekommen. (MSSQL 2008 R2 Express).
Behrooz

6
  1. Besuchen Sie das Kryotechniklabor in New York City.
  2. Friere dich für (ungefähr) 1990 Jahre ein.
  3. Holen Sie sich einen Job bei Planet Express.
  4. Kaufen Sie eine brandneue CPU. Erstellen Sie einen Computer, führen Sie das Programm aus und platzieren Sie es an einem sicheren Ort mit einer Pseudo-Perpetual-Motion-Maschine wie der Doomsday-Maschine.
  5. Warten Sie, bis die Zeitmaschine erfunden ist.
  6. Mit der Zeitmaschine in die Zukunft springen. Wenn Sie eine 1-Hz-128-Bit-CPU gekauft haben, fahren 3,938,453,320 days 20 hours 15 minutes 38 seconds 463 ms 463 μs 374 ns 607 psSie mit dem Start des Programms fort.
  7. ...?
  8. PROFITIEREN!!!

... Es dauert mindestens 10,783,127Jahre, selbst wenn Sie eine 1-Hz-CPU hatten, die 1,000,000,000,000,000(oder 1,125,899,906,842,624wenn Sie lieber ein binäres Präfix verwenden) mal schneller als eine 1-GHz-CPU ist.

Anstatt auf den Abschluss der Berechnung zu warten, ist es besser, Tauben zu füttern, die ihr Zuhause verloren haben, weil andere nTauben ihr Zuhause genommen haben. :((

Oder Sie können warten, bis der 128-Bit-Quantencomputer erfunden ist. Dann können Sie beweisen, dass die GUID nicht eindeutig ist, indem Sie Ihr Programm (möglicherweise) in angemessener Zeit verwenden.


Ich habe in dieser Antwort auf eine Superhelden-Referenz gewartet - scheitern Sie am Poster: p - trotzdem großartig.
IbrarMumtaz

4

Haben Sie es begin = begin + new BigInteger((long)1)anstelle von begin ++ versucht ?


2
Niemand hat für die Antwort gestimmt, die die Frage wirklich beantwortet: P
nawfal

4

Wenn die Anzahl der generierten UUIDs dem Moore'schen Gesetz entspricht, ist der Eindruck, dass auf absehbare Zeit die GUID nie ausgeht, falsch.

Mit 2 ^ 128 UUIDs dauert es nur 18 Monate * Log2 (2 ^ 128) ~ = 192 Jahre, bis uns alle UUIDs ausgehen.

Und ich glaube, dass in den letzten Jahren seit der Masseneinführung von UUID (ohne statistische Beweise) die Geschwindigkeit, mit der wir UUID generieren, viel schneller zunimmt, als es das Gesetz von Moore vorschreibt. Mit anderen Worten, wir haben wahrscheinlich weniger als 192 Jahre Zeit, bis wir uns mit der UUID-Krise befassen müssen, das ist viel früher als das Ende des Universums.

Aber da wir sie definitiv nicht bis Ende 2012 auslaufen lassen werden, überlassen wir es anderen Arten, sich um das Problem zu kümmern.


3

Die Wahrscheinlichkeit eines Fehlers im GUID-Generierungscode ist viel höher als die Wahrscheinlichkeit, dass der Algorithmus eine Kollision generiert. Die Wahrscheinlichkeit eines Fehlers in Ihrem Code zum Testen der GUIDs ist sogar noch größer. Gib auf.


2

Das Programm zeigt, obwohl es fehlerhaft ist, dass eine GUID nicht eindeutig ist. Diejenigen, die versuchen, das Gegenteil zu beweisen, verpassen den Punkt. Diese Aussage beweist nur die schwache Implementierung einiger GUID-Variationen.

Eine GUID ist per Definition nicht eindeutig, sondern per Definition sehr eindeutig. Sie haben gerade die Bedeutung von hoch verfeinert. Abhängig von der Version, dem Implementierer (MS oder anderen), der Verwendung von VMs usw. ändert sich Ihre Definition stark. (siehe Link im vorherigen Beitrag)

Sie können Ihre 128-Bit-Tabelle kürzen, um Ihren Standpunkt zu beweisen. Die beste Lösung besteht darin, eine Hash-Formel zu verwenden, um Ihre Tabelle mit Duplikaten zu verkürzen, und dann den vollen Wert zu verwenden, sobald der Hash kollidiert, und basierend darauf eine GUID neu zu generieren. Wenn Sie von verschiedenen Standorten aus ausgeführt werden, speichern Sie Ihre Hash- / vollständigen Schlüsselpaare an einem zentralen Ort.

Ps: Wenn das Ziel nur darin besteht, x verschiedene Werte zu generieren, erstellen Sie eine Hash-Tabelle mit dieser Breite und überprüfen Sie einfach den Hash-Wert.


2

Nicht hier auf dem Lagerfeuer zu p ** s, aber es passiert tatsächlich, und ja, ich verstehe den Scherz, den Sie diesem Kerl gemacht haben, aber die GUID ist nur im Prinzip einzigartig. Ich bin auf diesen Thread gestoßen, weil es einen Fehler gibt im WP7-Emulator, dh bei jedem Start wird beim ersten Aufruf die gleiche GUID ausgegeben! Wenn Sie also theoretisch keinen Konflikt haben können und Probleme beim Generieren der GUI auftreten, können Sie Duplikate erhalten

http://forums.create.msdn.com/forums/p/92086/597310.aspx#597310


1

Da ein Teil der Guid-Generierung auf der Zeit der aktuellen Maschine basiert, lautet meine Theorie, um eine doppelte Guid zu erhalten:

  1. Führen Sie eine Neuinstallation von Windows durch
  2. Erstellen Sie ein Startskript, das die Zeit auf 2010-01-01 12:00:00 zurücksetzt, sobald Windows gestartet wird.
  3. Unmittelbar nach dem Startskript wird Ihre Anwendung dazu veranlasst, eine Guid zu generieren.
  4. Klonen Sie diese Windows-Installation, damit Sie subtile Unterschiede ausschließen, die bei nachfolgenden Startvorgängen auftreten können.
  5. Erstellen Sie ein neues Image der Festplatte mit diesem Image und starten Sie den Computer einige Male.

0

Für mich ... garantiert die Zeit, die ein einzelner Kern benötigt, um eine UUIDv1 zu generieren, dass sie eindeutig ist. Selbst in einer Multi-Core-Situation, in der der UUID-Generator jeweils nur eine UUID für Ihre spezifische Ressource generieren kann (denken Sie daran, dass mehrere Ressourcen dieselben UUIDs vollständig verwenden können, jedoch unwahrscheinlich, da die Ressource von Natur aus Teil der Adresse ist), dann Sie hat mehr als genug UUIDs, um Sie zu halten, bis der Zeitstempel durchgebrannt ist. An diesem Punkt bezweifle ich wirklich, dass es dich interessieren würde.


0

Hier ist auch eine Lösung:

int main()
{
  QUuid uuid;
  while ( (uuid = QUuid::createUuid()) != QUuid::createUuid() ) { }
  std::cout << "Aha! I've found one! " << qPrintable( uuid.toString() ) << std::endl;
}

Hinweis: erfordert Qt, aber ich garantiere, dass es möglicherweise eines findet, wenn Sie es lange genug laufen lassen.

(Hinweis Hinweis: Jetzt, wo ich es mir anschaue, kann der Generierungsalgorithmus etwas enthalten, das verhindert, dass zwei nachfolgend generierte UUids kollidieren - aber ich bezweifle es irgendwie).


0

Die einzige Lösung, um zu beweisen, dass GUIDs nicht eindeutig sind, wäre ein World GUID Pool. Jedes Mal, wenn eine GUID irgendwo generiert wird, sollte sie bei der Organisation registriert werden. Oder zum Teufel, wir könnten eine Standardisierung einschließen, die alle GUID-Generatoren benötigen, um sie automatisch zu registrieren, und dafür eine aktive Internetverbindung!

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.