Cross-Plattform tauglicher GUID Generator



  • hustbaer schrieb:

    [...]Seede dir einen boost::mt19937 Generator über boost::random_device, dann kannst du dir GUIDs generieren soviel du willst.

    So, erstmal Danke für die ganzen Antworten.

    Also das mit dem random_device werde ich mal testen. Das klingt erstmal recht vielversprechend.

    Wegen vorangegangen Vorschlägen:
    Einfach nur Pseudorandomnummern zu erzeugen, reicht leider nicht. Irgendwoher muss ein Seed kommen, und dafür benutzt man üblicherweise die Systemzeit. Auf dem System, auf dem die Anwendungen laufen soll, wird die Zeit auf allen Plattformen synchronisiert, wodurch eine recht hohe Wahrscheinlichkeit besteht, dass man gleiche Zufallssequenzen auf verschiedenen Clustern produziert. Das darf aber nicht passieren.

    An die MAC-Addresse komme ich nicht plattformunabhängig ran (obwohl es überall eine gäbe, aber das System ist ziemlich heterogen und ich will möglichst wenig plattformspezifische Anteile in der Software haben).

    Das Boost auch einen nicht-deterministischen Generator liefert, ist mir entgangen. Das könnte aber die Lösung sein.

    Ansonsten werde ich wohl in den sauren Apfel beissen müssen, und die betriebssystemeigenen GUID-Funktionen wrappen. Das ist auf jeden Fall weniger aufwändig, als erst die MAC-Adresse oder ähnliches zu ermitteln, und dann daraus eine GUID zu erzeugen.

    EDIT: Nein, boost::random_device unterstützt Windows leider nicht. Das Ding kompiliert nur unter BSD oder Linux, wegen

    #if defined(__linux__) || defined (__FreeBSD__)
    

    in random_device.cpp . Eine Windows-Variante gibts nicht.



  • Hat mit dem Thema schon was zu tun. Wenn das erzeugen von echten Zufallszahlen trivial währe (was ich behaupte das es nicht ist) hätte Tachyon das Problem nicht 😉

    Das eine GUID auch ohne Netzwerkkarte erzeugt werden muss ist klar aber das eine Vorhanden ist entnahm ich schon der Aussage das es mit den Timestamps ein Problem gibt -> läßt auf Synchonisierung schließen -> Netzwerkkarte sehr wahrscheinlich
    Das die MAC auzulesen leider nicht Systemunabhängig ist hab ich mir fast gedacht, aber ne idee wars wert.

    Das mit dem Clown werd ich mir merken für mich hatte xD bis jetzt ca die selbe Bedetung

    Wenn mir wer "Unfug" vor den Kopf wirft ohne begründung muss ich nachfragen. Vielleicht weiß da wer was, dass ich noch nicht kenne.



  • Tachyon schrieb:

    EDIT: Nein, boost::random_device unterstützt Windows leider nicht. Das Ding kompiliert nur unter BSD oder Linux, wegen

    #if defined(__linux__) || defined (__FreeBSD__)
    

    in random_device.cpp . Eine Windows-Variante gibts nicht.

    Shit.
    Obwohl es recht einfach zu implementieren wäre.
    CryptGenRandom() is ja nu wirklich keine Hexerei.
    Vielleicht sollte ich nen Patch einschicken...



  • Tachyon schrieb:

    Wegen vorangegangen Vorschlägen:
    Einfach nur Pseudorandomnummern zu erzeugen, reicht leider nicht. Irgendwoher muss ein Seed kommen, und dafür benutzt man üblicherweise die Systemzeit. Auf dem System, auf dem die Anwendungen laufen soll, wird die Zeit auf allen Plattformen synchronisiert, wodurch eine recht hohe Wahrscheinlichkeit besteht, dass man gleiche Zufallssequenzen auf verschiedenen Clustern produziert. Das darf aber nicht passieren.

    Eine synchronisierte Systemzeit macht nur dann Probleme, wenn die Seeds alle zur gleichen Zeit genommen werden. Falls dem so ist hast du immernoch auf jedem Cluster irgendwo eine Kommunikationsschicht, die das Quatschen mit den anderen Rechnern übernimmt. Die Schicht ist eh schon Plattformabhängig, daher kannst du von ihr aus der Mac-Adresse oder IP-Adresse oder was auch immer eine plattformunabhängige Zahl generieren lassen, die von Cluster zu Cluster verschieden ist. Modifiziere die genommene Systemzeit in geeigneter Weise damit und du hast unterschiedliche Seeds, oder seh ich das falsch?



  • pumuckl schrieb:

    ...seh ich das falsch?

    Ja, aus meiner Sicht ist das Netzwerk plattformunabhängig, weil ich boost.asio benutze. Darüber gibt es aber keine Möglichkeit, an die MAC-Adresse heranzukommen. An IPs schon eher, aber die sind im System nicht eindeutig.



  • Keros schrieb:

    Hat mit dem Thema schon was zu tun. Wenn das erzeugen von echten Zufallszahlen trivial währe (was ich behaupte das es nicht ist) hätte Tachyon das Problem nicht.

    Aus informationstechnischer Sicht echte Zufallszahlen zu erzeugen, ist eigentlich kein großes Problem mehr. Die meisten Betriebssysteme bieten Funktionen dafür an, sofern die unterliegende Plattform ausreichend Informationen liefert.
    Das Problem ist, an diese Informationen heranzukommen. Außerdem kann sich die Repräsentation der Zufallszahlen sich von System zu System sehr stark unterscheiden.


  • Administrator

    @Tachyon,
    Kannst du nicht immer neue Seeds setzen, jedesmal wenn eine GUID erzeugt werden muss? Die GUID werden wohl kaum zur gleichen Zeit erzeugt. Zusätzlich könntest du std::clock aus <ctime> nehmen. Die Programmlaufzeit sollte sich wohl schon unterscheiden.
    Oder erzeugst du die GUIDs gleich beim Start des Programmes? Dann würde die Systemzeit allerdings reichen, da du wohl kaum alle Programme zur gleichen Zeit starten kannst 🙂

    Grüssli



  • Dravere schrieb:

    @Tachyon,
    Kannst du nicht immer neue Seeds setzen, jedesmal wenn eine GUID erzeugt werden muss? Die GUID werden wohl kaum zur gleichen Zeit erzeugt. Zusätzlich könntest du std::clock aus <ctime> nehmen. Die Programmlaufzeit sollte sich wohl schon unterscheiden.
    Oder erzeugst du die GUIDs gleich beim Start des Programmes? Dann würde die Systemzeit allerdings reichen, da du wohl kaum alle Programme zur gleichen Zeit starten kannst 🙂

    Grüssli

    Leider ist das nicht so einfach. Es gibt etwa 40 synchronisierte Cluster, auf denen das Programm mehr oder weniger parallel gestartet wird. Außerdem kann es sein, dass das Programm auf einem Cluster mehrere Male gestartet wird.
    In einer Monte-Carlo-Simulation habe ich herausbekommen, dass der clock + Zeitstempel auf einem Cluster sich immer mal wieder mit denen auf einem anderen Cluster überdeckt. Das ist also leider nicht ausreichend.
    Ich bin jetzt dazu übergegangen, den Seed aus einem SHA1-Hash zu erzeugen, den ich mit diversen Dingen füttere, die mir auf den Systemen zur Verfügung stehen.
    Drunter:

    `

    clock()

    time()

    /dev/urandom (falls vorhanden, ansonten den uninitialiserten Buffer in den ich normalerweise gelesen haette)

    den Hostnamen

    die Host IP (falls vorhanden)

    `

    Das scheint bis jetzt zu funktionieren. Ich muss das mal ein paar Tage laufen lassen.



  • Ich persönlich würde für Windows noch zusätzlich CryptGenRandom() statt /dev/urandom verwenden. Der Aufwand ist ja nicht gross (#ifdef WINDOWS + ein paar Zeilen Code).

    Oder aber gleich wie du es schon angedacht hast die GUID Generatoren vom OS kapseln. Könnte man auch mixen, also das was du jetzt machst als Fallback verwenden falls du für das spezielle OS keinen GUID Generator kennst, und ansonsten eben die OS Funktionen verwenden.



  • hustbaer schrieb:

    Ich persönlich würde für Windows noch zusätzlich CryptGenRandom() statt /dev/urandom verwenden. Der Aufwand ist ja nicht gross (#ifdef WINDOWS + ein paar Zeilen Code).

    Oder aber gleich wie du es schon angedacht hast die GUID Generatoren vom OS kapseln. Könnte man auch mixen, also das was du jetzt machst als Fallback verwenden falls du für das spezielle OS keinen GUID Generator kennst, und ansonsten eben die OS Funktionen verwenden.

    Also ich habe jetzt ein Funktionsmuster fertig gebastelt. Das Ding generiert einen SHA1-Hash (der Algo ist nach dem Pseudocode von Wikipedia implementiert) aus dem oben aufgezählten Input (also auf Windows ohne echte Zufallszahlen).
    Mit dem Hash (oder "Digest", wie die das immer nennen) wird dann boost::mt19937 als Engine geseeded. Damit wird dann eine UUID.v4 nach RFC 4122 (danke nochmal @Dravere) generiert.
    Bei meinen jetzigen Versuchen konnte ich keine Kollisionen feststellen. Ich werde morgen mal einen Intensivtest dafür fahren.



  • @Tachyon:
    Kollisionen bei Tests zu finden wird schwierig werden, selbst bei relativ "schwachen" Verfahren.
    Ich denke mir bloss auf Windows CryptGenRandom zusätzlich zu verwenden ist ja nicht sehr schwer, und kann eigentlich nur eine Verbesserung bringen.



  • Hast ja recht. Ich frickel das noch rein.


Anmelden zum Antworten