Hash-Bereiche erstellen die gleichverteilt sind..?

sirbender

Top Contributor
Hi,

ich erinnere mich dass man z.B. aus einem byte[] Hashes in Java erstellen kann. In einem naechsten Schritt wuerde ich gerne etwas mit den Hashes anstellen was jedoch nicht so wichtig sein soll. Was wichtig ist, ist dass ich die Hashes in Bins sortieren will. Sagen wird 10 Bins. Jedem Bin ist ein Thread zugeordnet der solbald Hashes vorliegen diese herrausnimmt und etwas damit macht. Die Hash-Bereiche fuer jedes Bin sollten so gewaehlt werden, dass in jedes Bin ca. gleich viele Hashes einsortiert werden und somit jeder Thread ungefaehr gleich viel zu tun hat.

1. Kann mit jemand eine Hash-Generierungsmethode vorschlagen. Eventuell Codebeispiel.
2. Wie kann ich diese Bins bzw. Hash-Bereiche erstellen. Wenn die Hashes aus einer Ziffer bestuenden (0-9) waere es einfach. Aber ich denke mal Hashes sind komplizierter und vielleicht nicht so einfach in Bereiche aufzuteilen die dann 'gleich verteilt' sind?

Danke,
sb
 
S

SlaterB

Gast
sei n Anzahl der Bins,
dann bilde die Summe über alle bytes[] im Array (oder nur der ersten x Elemente) und moduliere durch n, fertig

Beispiel: n = 10, ganz sparsam nur aufs erste byte
byte[] a = {133, 45, 65,23} -> 133 % 10 = 3
byte[] b = {-34, 65, 23} -> -34 % 10 = 6 (in Java -4, vorher ne hohe Zahl drauaddieren um sicher zu gehen)

könnte schon reichen, je nach Anforderung kannst du es komplizierter machen,
wenn das erste byte nicht zufällig genug ist dann wie gesagt Summe aller bytes,

wenn ärgerlicherweise die letzte Ziffer immer konstant sein sollte und die Anzahl bytes auch, dann ist modulo nicht so gut,
dann eben die Quersumme der Summe und dieses modulo n, wobei dann darauf achten ob n nicht viel zu hoch ist, und nur die niedrigen Bereiche drankommen,
na jetzt rate ich, für schwieriges gibts auch sicher irgendwo geeignetes
Hash function - Wikipedia, the free encyclopedia

> Wenn die Hashes aus einer Ziffer bestuenden (0-9) waere es einfach.
> Aber ich denke mal Hashes sind komplizierter und vielleicht nicht so einfach in Bereiche aufzuteilen die dann 'gleich verteilt' sind?

doch doch, jede gute Hashfunktion sollte in ihrem Bereich komplett zufällig sein, wenn nur 0 bis x mit x < n, dann nicht zu gebrauchen,
ansonsten kannst du immer % n oder ähnliches rechnen
(edit: und ziemlich spät fällt mir da immer ein Haken ein: Verteilung 0-9 gegeben, benötigt ist 0-6, also % 7, dann wären Wert 0, 1 und 2 doppelt so häufig vertreten wie die anderen)

so wie die Summe aller Bytes bzw. auch nur das erste Byte für sich pauschal erstmal ein normal-ordentlicher kürzerer Hash ist, wenn denn komplett zufällig, und % n komprimiert nur in kleineren Bereich

Java String verwendet
Java:
    /**
     * Returns a hash code for this string. The hash code for a
     * <code>String</code> object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using <code>int</code> arithmetic, where <code>s[i]</code> is the
     * <i>i</i>th character of the string, <code>n</code> is the length of
     * the string, and <code>^</code> indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
	int h = hash;
	if (h == 0) {
	    int off = offset;
	    char val[] = value;
	    int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Soweit ich mich erinnere, ist das nicht allgemein möglich. Es gibt ja keine "für jeden Fall perfekte" Hashfunktion. Man könnte jetzt sagen: "Joa, mach jeweils 4 bytes zu einem int und verXORe die dann (vielleicht noch mit irgendeiner primzahl reingemischt)" - das dürfte schon "gute" Ergebnisse liefern, aber: Wenn man 100 Elemente auf 10 Stellen abbilden will, und die gleichverteilt sein sollen, dann liegen in jedem bin 10 Elemente - es könnte also auch sein, dass man 10 Elemente in den Hash legt, das "zufällig" genau die 10 sind, die alle im gleichen Bin landen.

Der Beschreibung nach klingt das IMHO, als könnte da eine gemeinsame BlockingQueue für alle Threads geeigneter sein: Wenn etwas in der Queue liegt, holt sich der Thread, der gerade Zeit hat, etwas heraus (und ansonsten wartet er). Damit kann man sehr leicht 10 Threads "beschäftigt halten". Wenn es nur um eine gleichmäßige Verteilung an sich geht, könnte man (entweder brute force, oder mit irgendwas heap-artigem im Hintergrund) etwas machen, was darauf rausläuft, dass immer ein Element in das Bin gelegt wird, das im Moment die wenigsten Elemente enthält.
 

sirbender

Top Contributor
Die Summe koennte ich ja auch aus dem Hash selbst bilden, oder? Ich muss mir das mit dem Modulo mal anschauen...aber ich denke mal mit der Methode kann man dann auch einfach eindeutige Bereiche fuer 3, 12, 37 oder 337 Bins erstellen?

Danke,
sb
 
S

SlaterB

Gast
hab oben edit eingefügt:
doch doch, jede gute Hashfunktion sollte in ihrem Bereich komplett zufällig sein, wenn nur 0 bis x mit x < n, dann nicht zu gebrauchen,
ansonsten kannst du immer % n oder ähnliches rechnen
(edit: und ziemlich spät fällt mir da immer ein Haken ein: Verteilung 0-9 gegeben, benötigt ist 0-6, also % 7, dann wären Wert 0, 1 und 2 doppelt so häufig vertreten wie die anderen)

das muss man im Grunde überall beachten und macht es dann doch nicht mehr so leicht wenn man extreme Gleichverteilung möchte,
ein positives byte hat einen Wertebereich von 0-127, dort % 10 berechtet haben die 8 und 9 eine ca. 8% geringere Wahrscheinlichkeit als 0-7

Java:
public class Test {
    public static void main(String[] args)  {
        test(100);
        test(128);
    }

    private static void test(int max)  {
        int[] k = new int[10];
        Random r = new Random();
        for (int i = 0; i < 1000000; i++)   {
            int b = r.nextInt(max);
            k[b % 10]++;
        }
        System.out.println(Arrays.toString(k));
    }
}
Ausgabe:
Code:
[100544, 100125, 99941, 99777, 99643, 100385, 99733, 100057, 100095, 99700]
-> Zufallszahl 0-99, alle Ziffern etwa gleich um 100.000

[100907, 101734, 101472, 101818, 102050, 101566, 101537, 101782, 93546, 93588]
-> Zufallszahl 0-127, die letzten beiden deutlich kleiner

------

wenn man viele bytes aufaddiert wird der Fehler % 10 marginal,
wenn dagegen n auf 300 steigt dann wirds wieder spannender..

dagegen gibts auch ein Mittel, mal sehen ob es mir wieder einfällt oder es jemand anders postet oder bei Wiki schon steht

edit: bei der Zufallszahlermittlung und Abbildung auf einen kleineren Bereich kann man einfach zu hohe Zufallszahlen ignorieren,
bei 0-127 also neue Zufallszahlen >= 120 verwerfen und nur solche unter 120 nehmen, die % 10 wären dann gleichverteilt,
für Hash mit fest gegebenen Zahlen ist das nicht so hilfreich..
 
Zuletzt bearbeitet von einem Moderator:

sirbender

Top Contributor
Soweit ich mich erinnere, ist das nicht allgemein möglich. Es gibt ja keine "für jeden Fall perfekte" Hashfunktion. Man könnte jetzt sagen: "Joa, mach jeweils 4 bytes zu einem int und verXORe die dann (vielleicht noch mit irgendeiner primzahl reingemischt)" - das dürfte schon "gute" Ergebnisse liefern, aber: Wenn man 100 Elemente auf 10 Stellen abbilden will, und die gleichverteilt sein sollen, dann liegen in jedem bin 10 Elemente - es könnte also auch sein, dass man 10 Elemente in den Hash legt, das "zufällig" genau die 10 sind, die alle im gleichen Bin landen.

Hmmm...ich weiss nicht ob ich genau kapiert habe was du damit meinst. Warum sind die nicht gleichverteilt?

Der Beschreibung nach klingt das IMHO, als könnte da eine gemeinsame BlockingQueue für alle Threads geeigneter sein: Wenn etwas in der Queue liegt, holt sich der Thread, der gerade Zeit hat, etwas heraus (und ansonsten wartet er). Damit kann man sehr leicht 10 Threads "beschäftigt halten". Wenn es nur um eine gleichmäßige Verteilung an sich geht, könnte man (entweder brute force, oder mit irgendwas heap-artigem im Hintergrund) etwas machen, was darauf rausläuft, dass immer ein Element in das Bin gelegt wird, das im Moment die wenigsten Elemente enthält.

Danke erstmal fuer die Antwort. Ich habe eigentlich gar keine Threads oder einen Threadpool. Das war nur ein Beispiel um das Problem leichter verstaendlich zu machen.

Das Problem ist das ich:
1. diese genaue Zuordnung zu einem bestimmten Bin fuer einen gegebenen Hash brauche und
2. das die Hashes sehr ebenmaessig gefuellt sein muessen. Ganz kleine Abweichungen sind glaube ich ok.

Vielleicht kann ja jemand eine Methode nenen die dieses Problem am ehesten loest. Ich koennte dann ein paar Tests machen und schauen ob es fuer meine Zwecke ausreicht.
 
S

SlaterB

Gast
es sollte wohl heißen 'wenn man 60x würfelt (Hash teilweise genauso zufällig) erhält man nicht genau 10x eine 1, 10x eine 2 usw. sondern je nach Zufall auch 60x dieselbe Zahl'

wenn du also ein Einträge so verteilen willst, dass überall gleich viele sind, dann mach das einen Eintrag nach dem anderen,
nicht abhängig von einer Hashfunktion mit unbekannten Ausgang
 

Marco13

Top Contributor
Jein - das Problem ist ja sozusagen, dass der Hashwert eben NICHT zufällig ist. Egal, wie man die Hashfunktion definiert, um 100 Elemente gleichmäßig auf 10 Bins zu verteilen: Es gibt immer 10 Elemente, die im gleichen Bin landen, und wenn man nun zufällig gerade diese 10 Elemente behandeln muss, landen sie im gleichen Bin. Wie "gut" eine Hashfunktion in diesem Sinne ist, hängt also nicht nur von der Hashfunktion, sondern auch gleichermaßen von den zu hashenden Daten ab. Oder als Plakativbeispiel:
Code:
for (int i=0; i<100; i++)
{
    byte data[] = new byte[123]; // Enthält nur Nullen...
    int magicHashIndex = computeHash(data);
    store(magicHashIndex, data);
}
Wie muss die "computeHash"-Methode aussehen, damit in diesem Beispiel genau 10 verschiedene indizes rauskommen? (Es würde schon reichen, wenn du sagen könntest, wie sie aussehen müßte, damit ZWEI verschiedene indizes rauskommen ;) ohne ein System.identityHashCode(data) geht da nicht viel...)

EDIT: So als Nachtrag: Wenn man von Anfang an ALLE datensätze hätte, könnte man da natürlich was machen - aber dann würde man für die Implementierung dieser HashMap wohl sowas wie eine HashMap verwenden (klingt absurd, könnte aber Sinn machen - je nachdem, worum es da genau geht...)
 

sirbender

Top Contributor
Ok. Ich glaube wir reden aneinander vorbei.

1. Ich moechte eine standardtisierte Hashmethode nutzen die auch z.B. bei Javascript verfuegbar ist. Ich will nicht meine eigene Hashmethode stricken. Auch sollte sie auch nur bei leicht unterschiedlichen (z.B. swap von 2 Elementen) byte[] unterschiedliche Hashes erzeugen. Bei identischen byte[] soll aber immer der gleiche Hash erzeugt werden.

2. Nehmen wir an ein Hash besteht aus einer Zahl mit 5 Ziffern, also: 01234, 43210, 94387, usw. Da waere die Einteilung in 10 Bins sehr simpel. Bin 1 kriegt Hashes von 0000 bis 10000, usw.
Ich nehme mal stark an dass bei byte[] die mit Zufallszahlen gefuellt werden dann auch die Verteilung der Hashes auf die Bins recht gleichmaessig waere, oder? Oder wuerde die Hashfunktion bestimmt Wertebereiche, also Bins bevorzugen?


Danke,
sb
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Hash Size (Sha 256) Allgemeine Java-Themen 5
Kirby.exe Hash Map Allgemeine Java-Themen 24
L Hash-Tabelle Allgemeine Java-Themen 2
J Passwort Verschlüsselung hash Allgemeine Java-Themen 2
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
T Hash von *.class-Datein überprüfen Allgemeine Java-Themen 1
W Passwort Clientseitig sicher ablegen ohne Hash Allgemeine Java-Themen 2
R Großes Hash-Set erzeugen Allgemeine Java-Themen 12
R MD5-Hash eines Strings bestimmen Allgemeine Java-Themen 2
J Hash aus Verzeichniss generieren Allgemeine Java-Themen 2
J MD5-Hash einer Datei Allgemeine Java-Themen 4
O Hash Wert von Passwörter erstellen (SHA) Allgemeine Java-Themen 9
F Passwort hash Allgemeine Java-Themen 8
M@rk MD5 Hash Allgemeine Java-Themen 3
C HASH Algorithmus 2 Strings ergeben das Selbe. Allgemeine Java-Themen 2
minzel Hash-Algorithmus Allgemeine Java-Themen 9
H Hash Tabelle einlesen und die Werte an ein Array übergeben Allgemeine Java-Themen 10
M Hash Tables Allgemeine Java-Themen 5
I hash-algorithmus Allgemeine Java-Themen 9
C Mouse Bereiche - Besser notieren - Tipps Allgemeine Java-Themen 2
Zrebna Testkonzept erstellen - Verständnisschwierigkeiten Allgemeine Java-Themen 6
dokan wie kann ich eine funktionierende Suchleiste erstellen Allgemeine Java-Themen 1
Thomasneuling Java Jar datei erstellen, von Projekt, dass auch Javafx Dateien, FXML Dateien und CSS Dateien, sowie Bilder enthält? Allgemeine Java-Themen 14
berserkerdq2 SceneBuilder GUI erstellt, nun muss ich noch ein Polygon erstellen, ist die Connection möglich? Allgemeine Java-Themen 3
berserkerdq2 Was heißt es mit FXML Listener zu setzen ind Buttons zu erstellen? Allgemeine Java-Themen 6
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
D Open Source Library zum erstellen von PDFs Allgemeine Java-Themen 1
A Java Programm erstellen hilfe Allgemeine Java-Themen 10
J Power Point erstellen inklusive Diagramm Allgemeine Java-Themen 12
F IDEA IntelliJ Java Songliste erstellen Allgemeine Java-Themen 6
N Tree erstellen Allgemeine Java-Themen 8
berserkerdq2 Threads, wie genau läuft das in Java ab? (Ich kann Threads erstellen und nutzen, nur das Verständnis) Allgemeine Java-Themen 6
berserkerdq2 Kann keine Labels erstellen, was ist hier syntaktisch falsch Allgemeine Java-Themen 5
_user_q Verknüpfung einer .jar-Datei (liegt z. B. auf dem Desktop) im Autostart-Ordner erstellen? Allgemeine Java-Themen 20
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Trace-Tabelle erstellen Allgemeine Java-Themen 3
M Excel Datei Erstellen Allgemeine Java-Themen 2
OnDemand Erstellen von Quartz Jobs pro Aufgabe oder zusammenfassen Allgemeine Java-Themen 7
H Matrix ohne Array erstellen Allgemeine Java-Themen 9
R Geometry erstellen die abhängig von Variablen ist Allgemeine Java-Themen 6
Gaudimagspam Skip Liste erstellen in Java Allgemeine Java-Themen 3
Avalon DTO aus mehrere Entitäten erstellen Allgemeine Java-Themen 5
Kirby.exe Distanz Map für die Distanztransformation erstellen Allgemeine Java-Themen 1
Avalon Data Transfer Objekte aus Datenbank erstellen Allgemeine Java-Themen 8
M Registry Autostart Eintrag mit Java erstellen (über Windows cmd) Allgemeine Java-Themen 7
B .txt Datei erstellen und auslesen bzw. schreiben Allgemeine Java-Themen 6
M Java 2D Array für ein Grid erstellen ? Allgemeine Java-Themen 2
B Datei/Ordner auf Server zugreifen/erstellen Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
M Rectangle mit Java erstellen? Allgemeine Java-Themen 9
G Fläche erstellen mit Entfernungen Allgemeine Java-Themen 1
E Eigenen "Aufzählungstyp" erstellen - mit enum ? Allgemeine Java-Themen 18
T Multithreading: Wie viele Threads sollte ich erstellen? Allgemeine Java-Themen 12
B Rangliste erstellen Allgemeine Java-Themen 13
D 2,3-Baum rekursiv erstellen Allgemeine Java-Themen 20
D Datentypen 2-3 Baum erstellen mit geordnetem int-array Allgemeine Java-Themen 0
L SQL Datei in Eclipse erstellen Allgemeine Java-Themen 3
J Datenstruktur für eine Map erstellen Allgemeine Java-Themen 2
J File in Package erstellen & lesen mit Programmstart in externe Projekt Allgemeine Java-Themen 3
E Erstellen einer Liste mit einer maximalen Menge an Elementen Allgemeine Java-Themen 13
E Ts3API Subchannel erstellen und rein moven !! Allgemeine Java-Themen 0
J Eigene Api erstellen und dann auch verwenden - Ordnerstruktur Allgemeine Java-Themen 1
S GetMethode erstellen mit Hilfe von Parametern Allgemeine Java-Themen 9
T 2D-Grafik Chart als Image erstellen Allgemeine Java-Themen 3
I Fehler beim Ant-Package erstellen mit Java 9 Allgemeine Java-Themen 1
N Bei Mouse Events nicht mehrere Objekte erstellen Allgemeine Java-Themen 13
S Compiler-Fehler IntelliJ Projektdatei lässt sich nicht erstellen. Allgemeine Java-Themen 15
M 2D Array mit unterschiedlichen Längen erstellen und befüllen Allgemeine Java-Themen 11
E Swing Buttons auf knopfdruck(anderer Button) erstellen Allgemeine Java-Themen 6
S TestNG Eclipse: Reporting erstellen/ verändern Allgemeine Java-Themen 0
F .jar erstellen und starten Allgemeine Java-Themen 15
M Array aus Thread Objekten erstellen Allgemeine Java-Themen 2
N 1000 MQTT Messages die Sekunde - 1000 Threads erstellen ? Allgemeine Java-Themen 10
Tommy Nightmare Klassen Globale Klassen erstellen Allgemeine Java-Themen 7
K Datei (CSV-ähnlich) in Java einlesen & mit teil der Daten Graphen erstellen Allgemeine Java-Themen 9
S Maven Jars dynamisch laden / Plugin-Struktur erstellen Allgemeine Java-Themen 14
T 32-Bit Applikationen mit Eclipse erstellen Allgemeine Java-Themen 4
R Input/Output RTF erstellen? Allgemeine Java-Themen 2
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
S Klassen Klassen "virtuell" erstellen Allgemeine Java-Themen 5
P mehrer Verschiedene Objekte in einer Klasse erstellen. Allgemeine Java-Themen 4
M Dokument erstellen Allgemeine Java-Themen 0
S Java API für GitHub erstellen Allgemeine Java-Themen 14
T Ant Jar Datei per Ant in Eclipse erstellen Allgemeine Java-Themen 2
4a61766120617274697374 Hintergrundjobs(tasks) in Java erstellen Allgemeine Java-Themen 3
K Eigene API erstellen? Allgemeine Java-Themen 13
N Benutzeroberfläche erstellen Allgemeine Java-Themen 5
Thallius Eigenes Message Center erstellen Allgemeine Java-Themen 3
perlenfischer1984 Mehrere Komponenten erstellen Allgemeine Java-Themen 3
B jni - Headerdatei erstellen Allgemeine Java-Themen 3
Neumi5694 Operatoren regEx für das Erstellen eines Strings verwenden Allgemeine Java-Themen 3
I Methoden Schnelle Hilfe benötigt - Kleines Video/Slideshow aus mehreren Bildern erstellen Allgemeine Java-Themen 3
B automatisch benannte arrays erstellen Allgemeine Java-Themen 9
F URI-Scheme mit Java unter MacOS erstellen? Allgemeine Java-Themen 0
S Mit Generics Klasse erstellen die selbst T erweitert..? Allgemeine Java-Themen 4
J Java Software Compare Files und Neue File erstellen Allgemeine Java-Themen 0
M Textfile erstellen Allgemeine Java-Themen 11
L Wie kann ich einen Keystore aus existierenden Zertifikaten erstellen? Allgemeine Java-Themen 1
K Fehler beim erstellen von .jar Datei Allgemeine Java-Themen 3
D Ordner auf Desktop erstellen(Pc unabhängig) Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben