Forum: PC-Programmierung Die Größe von 256 Bit Hashes vergleichen


von CrabUser1 (Gast)


Lesenswert?

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/

von Einer (Gast)


Lesenswert?

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!

von Einer (Gast)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Florian F. (flof3000)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von Einer (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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

von CrabUser1 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.