Die Standardbibliothek von Rust unterstützt soweit ich weiß Integer Datentypen bis 128 Bit. Ich nutze den sha3 crate und erzeuge damit 256 Bit Hashes. Wenn ich einen solchen Hash berechne erhalte ich die 32 Bytes in Form eines GenericArrays. Ich möchte zwei verschiedene 256 Bit Hashes miteinander auf ihre Größe hin vergleichen. Also so was wie if hash1 < hash2. Ich brauche im Grunde doch Datentypen die mehr als 128 Bit Integer Werte abbilden können oder nicht? Ich habe ausprobiert was passiert wenn ich zwei GenericArrays mit einfachen Vergleichsoperatoren vergleiche. Bei ein paar Versuchen scheint es richtig zu funktionieren. Also so was wie if hash1 < hash2. Soll das heißen ich kann die Hashes als Bytes auf ihre Wert Größe hin so vergleichen? Aber was genau wird da verglichen? Und als big oder little endian? https://docs.rs/generic-array/0.14.4/generic_array/struct.GenericArray.html https://docs.rs/sha3/0.9.1/sha3/
Problem Nr.1: Der Begriff "Größe" ist in diesem Kontext falsch. Du vergleichst nicht die "Größe", sondern den "Wert". CrabUser1 schrieb: > Ich brauche im Grunde doch Datentypen die mehr als 128 Bit Integer Werte > abbilden können oder nicht? Nein. CrabUser1 schrieb: > Soll das heißen ich kann die Hashes als Bytes auf ihre Wert Größe hin so > vergleichen? Ja, natürlich. > Aber was genau wird da verglichen? Und als big oder little endian? Genau genommen, ist ein Digest keine "Zahl", sondern nur ein bestimmte Anzahl von Bytes. Und wenn man einen Byte-String vergleicht, bzw. den als Integer interpretiert, interpretiert man Byte-Strings "natürlich" als Big-Endian. Aber es ist eben kein Integer, sondern ein Byte-String. Einen Byte-String kann man aber ganz einfach auf Gleichheit vergleichen oder eben auch lexikalisch sortieren. Und genau das machen die Vergleichsoperatoren mit Byte-Strings, sie vergleichen lexikalisch. Als Sonderfall ist der lexikalischen Vergleich zweier Strings mit gleicher Länge identisch zu einem Integer-Vergleich, wenn man diese Strings als Big-Endian-Integer interpretiert. Das gilt aber nur für Strings gleicher Länge!
Achso, in vielen Krypto-Algorithmen werden Byte-Sequenzen (Byte-Strings) als Integer-Zahlen interpretiert. Das ist dann aber Teil der Algorithmus-Spezifikation, und nach "außen" nicht sichtbar bzw. irrelevant. Wie der Algorithmus Byte-Sequenzen verarbeitet und wie ein Hash erzeugt wird, spielt keine Rolle. Das sind alles nur Bytes.
CrabUser1 schrieb: > Ich möchte zwei verschiedene 256 Bit Hashes miteinander > auf ihre Größe hin vergleichen. Wozu? Das ist bei Hashes normalerweise eine sinnlose Operation. Riecht also schwerstens nach A/B Problem, also stelle uns mal Deine eigentliche Aufgabe und nicht den halben Lösungsweg vor. Falls das Sortierung zur Anzeige o.ä. ist: Einfach nach String konvertieren und die Strings sortieren.
Jim M. schrieb: >> Ich möchte zwei verschiedene 256 Bit Hashes miteinander >> auf ihre Größe hin vergleichen. > > Wozu? Das ist bei Hashes normalerweise eine sinnlose Operation. Sinnlos ja, aber Bitcoin funktioniert doch genau so. Generieren sie einen Hash mit x 0 bytes am Anfang, also kleiner (n-x)**2.
Jim M. schrieb: > Riecht also schwerstens nach A/B Problem, also stelle uns mal Deine > eigentliche Aufgabe und nicht den halben Lösungsweg vor. Ja, sieht schwer danach aus. Bitte einmal das Problem beschreiben. > Falls das Sortierung zur Anzeige o.ä. ist: Einfach nach String > konvertieren und die Strings sortieren. Oder als zwei 128bit-Zahlen (höherwertiger und niederwertiger Teil) darstellen und diese einzeln vergleichen. Der Größer-/Kleiner-/Gleich-Vergleich ist trivial für eine in zwei mal 128-Bit aufgeteilte 256-Bit Zahl. Einfach mal drüber nachdenken, dann kommst du auch selbst darauf, wie man so etwas implementiert.
Florian F. schrieb: > Sinnlos ja, aber Bitcoin funktioniert doch genau so. Generieren sie > einen Hash mit x 0 bytes am Anfang, also kleiner (n-x)**2. Statt den ganzen Hash zu vergleichen, ist ein Vergleich der führenden Bytes/Worte gegen Null, die Null sein sollen aber auch da effizienter und einfacher.
MaWin schrieb: > Oder als zwei 128bit-Zahlen (höherwertiger und niederwertiger Teil) > darstellen und diese einzeln vergleichen. So ein Bullshit. Der Digest ist ein GenericArray und das implementiert den Trait Ord: https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html Also einfach gewünschten Vergleich hinschreiben und fertig. Es ist überdeutlich dass Du sowieso noch nie in Rust programmiert hast oder auch in einer anderen Sprache außer Low-Level-C. Du bist einfach nur Ahnungslos und solltest Dich an Dieter Nuhr halten.
Einer schrieb: > So ein Bullshit. Bisher war die Diskussion konstruktiv und ohne Beleidigungen. Denk mal darüber nach. > Der Digest ist ein GenericArray und das implementiert den Trait Ord: Ok, dann ist doch alles in Ordnung. Das habe ich jetzt nicht extra überprüft. Kein Grund für Beleidigungen.
Also, nach einem Blick in die Doku: GenericArray Ord ist als slice-cmp implementiert. Was am Ende so implementiert ist für u8-arrays: https://doc.rust-lang.org/src/core/slice/cmp.rs.html#187 D.h. lexikographischer Vergleich, beginnend ab Byte 0. Für nicht-u8-arrays entsprechend funktional gleich: https://doc.rust-lang.org/src/core/slice/cmp.rs.html#167
Danke für die konstruktiven Antworten. Wieder was gelernt. Und ja, es geht um die Implementierung eines proof of work Konzepts. Dafür werden Hashes generiert, bis eine gefunden ist, die eine vorgegebene Anzahl an führenden Nullen aufweißt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.