Bash Einweg-Hashfunktion programmieren, die feste Ausgabelänge hat und pseudozufällig ist

CyborgBeta

Captain
Registriert
Jan. 2021
Beiträge
3.660
Hallo, ich möchte aus 4 Buchstaben (aus a-z) einen 4-stelligen Hashwert der Form 0000 bis 9999 berechnen.

Nun gibt es ja 26^4=456976 Kombinationsmöglichkeiten der 4 Buchstaben, aber nur 10.000 unterschiedliche Ausgabewerte (klar).

Es muss also (und soll auch) Kollisionen geben. Meine Frage wäre, wie ich erreichen könnte, dass zum Beispiel "aaaa" einen komplett anderen Hashwert erzeugt als "baaa" - oder als "abaa" (Pseudozufälligkeit)?

Mein bisheriger Versuch:

Java:
public class Names {
    public static void main(String[] args) {
        System.out.println(hashCode("aaaa"));
        System.out.println(hashCode("zzzz"));
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                String s1 = (char) ('a' + i) + "" + (char) ('a' + j);
                String s2 = (char) ('z' - i) + "" + (char) ('z' - j);
                System.out.println(s1 + " " + s2 + " " + hashCode(s1) + " " + hashCode(s2));
            }
        }
    }

    public static String hashCode(String s) {
        if (s.length() < 4) {
            s += "a".repeat(4 - s.length());
        }
        int hash = 0;
        int multiplier = 1;
        for (int i = 0; i < 4; i++) {
            hash += multiplier * (s.charAt(i) - 'a');
            multiplier *= 26;
        }
        return String.format("%04d", (int) (10000.0 / Math.pow(26, 4) * hash));
    }
}

Anschließend möchte ich aus der hashCode-Methode dann noch ein Bash-Script (bzw. Funktion) machen.

Habt ihr da Ideen? Mir schwirrt bei int-Werten auch die magische Primzahl 31 im Kopf herum, aber ich weiß nicht, wie ich das umsetzen könnte, und ob das sinnvoll wäre.
 
Spaß, Hobby, nehme ich an und nicht für irgendwas ernsthaftes einzusetzen? Sonst fehlen Informationen zum Anwendungsfall und solltest du dann nicht selber implementieren.
 
CyborgBeta schrieb:
Hallo, ich möchte aus 4 Buchstaben (aus a-z) einen 4-stelligen Hashwert der Form 0000 bis 9999 berechnen.
Jage das durch eine fertige Hash-Funktion deiner Wahl und das Ergebnis davon modulo 10000 nehmen.
 
  • Gefällt mir
Reaktionen: kieleich und Tornhoof
foofoobar schrieb:
@foofoobar Das Ergebnis ist dann nicht mehr gleichverteilt, d.h. manche Inputs haben höhrere Chancen für Kollisionen als andere. Ob das ein Problem ist? Keine Ahnung, kommt natürlich auch auf den Anwendungsfall an.

CyborgBeta schrieb:
Weil alle Anwendungsfälle durch bestehende Verfahren abgedeckt sind und man quasi zwangsläufig Fehler einbaut wenn man sowas selber implementiert.
 
  • Gefällt mir
Reaktionen: CyborgBeta
CyborgBeta schrieb:
Schöne Prüfsummen für URL-Bestandteile berechnen
wenn du prüfsummen willst, dann nimm auch ein existierendes verfahren dafür, crc16 z.b. gibt dir eine 4 byte checksumme, wenn diese länge dein ziel ist.
 
  • Gefällt mir
Reaktionen: TomH22
BeBur schrieb:
Ob das ein Problem ist?
Ja, ist es.

Gewünschte Eigenschaften der Hashwerte:

  • eindeutig
  • feste Länge
  • kollisionsresistent
  • einwegig
  • deterministisch
  • pseudozufällig
  • gleichverteilt

Ergänzung ()

0x8100 schrieb:
dann nimm auch ein existierendes verfahren dafür
Dann nenn mir bitte ein bestehendes Verfahren, das meine Anforderungen genau erfüllt.
 
BeBur schrieb:
Das Ergebnis ist dann nicht mehr gleichverteilt, d.h. manche Inputs haben höhrere Chancen für Kollisionen als andere. Ob das ein Problem ist? Keine Ahnung, kommt natürlich auch auf den Anwendungsfall an.
warum?
wenn die letzten Zeichen des hashes ein Muster aufweisen, wäre es keine gute Hashfunktion
 
xammu schrieb:
Das widerspricht sich.
Nö:

1744454020366.png

https://www.tu-chemnitz.de/informatik/ThIS/vlzits/hash.html
Ergänzung ()

Prinzipiell möchte ich folgende Eigenschaften erreichen:

  • Geringe Wahrscheinlichkeit von Kollisionen der Hashwerte für den Eingabewertebereich, also möglichst eine Gleichverteilung der Hashwerte auf die erwarteten Eingabewerte.
  • Surjektivität – Kein Ergebniswert (Hashwert) soll unmöglich sein, jedes Ergebnis (jeder Hashwert im definierten Wertebereich) soll tatsächlich vorkommen können.
  • Chaos oder Lawineneffekt – Die Hashfunktion soll eine gute Diffusion besitzen; ähnliche Quellelemente (Eingabewerte) sollen zu völlig verschiedenen Hashwerten führen. Im Idealfall verändert das Umkippen eines Bits in der Eingabe durchschnittlich die Hälfte aller Bits im resultierenden Hashwert.

Optional, aber wünschenswert:

  • Konfusion – Vom Hashwert sollen keine Rückschlüsse auf den Eingabewert gemacht werden können.
  • .

Siehe auch: https://de.wikipedia.org/wiki/Hashfunktion#Kriterien
 
Bei dir ergeben mindesten 4 Eingabewerte den selben Hash. Wo ist das schwach kollisionfrei.

Mich interessiert der Sinn hinter deinem Vorhaben. Sonst nimm eine vorhandene Hasfunktion.
 
der erste fehler in bezug auf crypto ist, dass man glaubt, es selber besser machen zu können. nimm ein etabliertes verfahren und gut ist.
 
  • Gefällt mir
Reaktionen: Myron, up.whatever, BeBur und eine weitere Person
CyborgBeta schrieb:
Dann nenne doch bitte eins, dessen Ausgabe diese Länge hat und nur aus Ziffern besteht.
es gibt keine kryptografisch sichere hashfunktion, die deinen anforderungen genügt und deren ausgabe aus nur 4 zeichen, die auch nur 0-9 enthalten dürfen, besteht. case closed.
 
Zurück
Oben