Wahrscheinlichkeitsfrage bei hashCode() mit modulo

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
Hi, beim Start meiner App öffne ich einen Socket, damit beim Start einer zweiten Instanz dies scheitert (Socket ist schon offen), und ich das Programm beenden kann, da nicht 2 Instanzen laufen sollen. Jetzt sollen aber nur 2 Instanzen dann nicht laufen können, wenn es die gleiche JAR war, d.h.

Java:
String path = new File("").getAbsolutePath();

liefert bei beiden das selbe. Da ich den Socket davon abhängig machen muss, dachte ich mir ich leite den Port von dem hashCode des Pfades ab. Da der Port ja nicht beliebig sein darf, muss ich sicherstellen dass der Wert 1) positiv ist und 2) im gültigen Wertebereich für Ports liegt. Für zweiteres nutze ich modulo, also das ganze sieht so aus:

Java:
/* get runtime environment path */
		String path = new File("").getAbsolutePath();

		/*
		 * Open a socket using a port derived from the database path. Exit if an
		 * instance with the same database is already running
		 */
		try {
			int greatestPort = 65535;
			new ServerSocket(Math.abs(path.hashCode()) % greatestPort, 0,
					InetAddress.getByName("localhost"));
		} catch (BindException e) {
			e.printStackTrace();
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(-1);
		}

hashCode() kann ja auch nicht zu 100% garantieren, dass nicht 2x das selbe rauskommt bei 2 verschiedenen Strings. Aber es ist ja doch so implementiert dass es "quasi-unmöglich" ist. So, nun meine Frage: Inwiefern verfälsche ich die Sicherheit von hashCode() durch das modulo? Ist das okay, oder seht ihr da evtl Probleme in der Praxis?

Dreist gesagt könnte ich es jetzt auch so formulieren: Wie würdet ihr dat machen, gebt ma' Code her aber zack zack :D (Falls ihr dieses Vorgehen für zu unsicher anseht)
 

javimka

Top Contributor
Der Hashwert ist ja ein Integer, also gibt es 2^32 = 4 Mrd Möglichkeiten dafür. Wenn du diese Möglichkeiten Modulo 65533 = 2^65 (ungefähr) rechnest, vermindest du die Sicherheit um 2^16, also um das 65000-fache oder noch anders gesagt, es existieren nur noch die Wurzel an Möglichkeiten. Das hört sich jetzt schrecklich an, aber wahrscheinlich wird dein Programm, so toll es auch sein mag, nicht zig-1000 Mal gleichzeitig gestartet ;)
ABER, statistisch gesehen wird jeder 65000 Versuch, das Programm doppelt zu starten gelingen.

Ich habe ehrlich gesagt keine Ahnung, wundere mich nur, ob du wohl Probleme bekommen würdest, wenn du dein Socket nun mit dem Port 80 starten würdest, der ja für HTTP vorgesehen ist, oder mit einem anderen Port, der von anderen Programmen benutzt wird.
 

Marco13

Top Contributor
Ja, die ersten... ähm .. ich glaube 1024 Ports sind doch sowieso irgendwie "reserviert", und sollten nicht für eigene Programme verwendet werden?!
 
S

Spacerat

Gast
Also der Vergleich, ob da 2x aus dem indenischen Jar gestartet wurde mag ja mit [c]hashCode()[/c] gehen. Aber aus dem HC einen Port abzuleiten ist die weniger gute Idee, weil man so zufällig auf einem schon belegten Port landen könnte, auf welchem keineswegs eine Instanz deiner Software laufen muss (wie mein Vorredner schon sagt: z.B. HTTP-80). Ausserdem könntest du mit deinem Beispiel auch in dem Bereich landen (0-1023), in welchem du administrative Rechte benötigst, um ihn zu öffnen.
Ich persönlich würde (Prinzipiell kann jede Java-Anwendung solch einen IIP* gebrauchen) der Anwendung einen Port für allgemeinen Austauch mit anderen Java-Anwendungen und einen privaten Port implementieren und dabei die Ports keinesfalls "zufällig" vergeben.

*IIP: InformationInterchangePort
 

hdi

Top Contributor
Danke an alle, und Spacerat, kannst du mir da noch etwas weiterhelfen? Wie meinst du das konkret? Wie kann ich denn zB die Info des Pfades von einer App in eine andere übergeben, ohne einen globalen Server mit RMI usw. Findet ihr den Ansatz mit dem Socket schon falsch? Ich hab das irgendwo aus Google gezogen mal... Im Prinzip benötigt meine Anwendung ja gar keinen Socket und sollte auch keinen Port belegen, das ist ne 100% Standalone Client-Anwendung. Das ist halt ein Workaround gewesen... (Was ich immerhin schöner fand als das jetzt über zB Lockfiles zu lösen, wobei man da bestimmt auch erstmal wissen muss wie man es wirklich richtig macht)
 
S

Spacerat

Gast
Diese Idee mit den Sockets ist ja meistens gut und schön, aber in deinem Fall dann wohl weniger von Nöten. Da würde ich doch lieber zu Lockfiles greifen. Natürlich mit der Auflage, dass der Lockfile die ganze Laufzeit über geöffnet bleibt, d.H. also: kein anderes Programm kann sie löschen, lesen oder beschreiben. Da kann man dann auch den HC für den Dateinamen verwenden.
Nur nebenbei: Die Sache mit dem IIP ist dann mehr oder weniger auch überzogen. Die Idee dazu lieferte mir AReXX, eine Scriptspache auf dem Amiga, mit welcher verschiedene Anwendungen lokal miteinander Kommunizieren konnten (ohne TCP/IP, Netzwerk und, und, und...). Ich vermute mal, das solch ein Mechanismus mit RMI realisiert werden kann. Aber WG: Für deinen Fall ziemlich überzogen. Eine Anwendung, die sonst nichts mit Netzwerk zu tun hat, sollte meiner Meinung nach auch nicht solche Ressourcen verwenden.
 

Illuvatar

Top Contributor
Du könntest auch mal das hier anschauen. Da wird auch beschrieben, wie du mit der bereits offenen Applikation kommunizieren kannst (d.h., rausfinden ob beides die gleiche jar ist).

Apropos gleiche jar: [c]new File("").getAbsolutePath();[/c] muss nicht das Verzeichnis der jar sein! Wenn z.B. [c]java -jar foo\bar.jar[/c] ausgeführt wird, dann ist das Verzeichnis foo nicht mehr in dem oben erhaltenen Pfad enthalten.

Irgendwie über den ClassLoader kann man aber das tatsächliche File-Objekt der jar erhalten, das weiß ich noch... ich vergess nur immer, wie das geht ;)
 

hdi

Top Contributor
Danke, dein Link ist super! Zwar durchaus etwas umständlich und für mich wohl overkill, da Fehler jetzt nicht unbedingt in etwas "Schlimmem" enden können bei mir, aber dieses Framework zu haben ist ja doch ziemlich cool! Jetzt muss ich nur noch rausfinden was der echte Jar-Pfad ist, weil ich das dann in die Lock-Datei schreib. Werd mal mit dem ClassLoader rumspielen...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T HashCode korrekt Allgemeine Java-Themen 7
F Methoden hashCode() & equals() Allgemeine Java-Themen 13
A JUnit/Hashcode Problem Allgemeine Java-Themen 5
I HashMap key wird nicht erkannt trotz überschriebener equals/hashCode Methode Allgemeine Java-Themen 6
pg1337 hashCode() verändert sich Allgemeine Java-Themen 15
A Input/Output Serialisierung und Object.hashCode() Allgemeine Java-Themen 3
M hashCode() Allgemeine Java-Themen 3
A HashCode von DatagrammPacket(content) erzeugen. Allgemeine Java-Themen 3
N hashCode() für zwei ints Allgemeine Java-Themen 5
C hashCode() Allgemeine Java-Themen 2
fastjack jUnit und Test von equals, hashCode, toString Allgemeine Java-Themen 11
Guybrush Threepwood HashCode-Generierung Allgemeine Java-Themen 4
G hashCode() == Speicheradresse? => warum nur int? Allgemeine Java-Themen 28
X hashCode() Berechnung Allgemeine Java-Themen 5
M hashCode Allgemeine Java-Themen 9
vogella Überschreiben von equals und hashcode für Collection Allgemeine Java-Themen 7
T hashCode() erzeugen. Allgemeine Java-Themen 11
T eine Frage zu hashCode() Allgemeine Java-Themen 11
U Hashtables und hashCode() Allgemeine Java-Themen 6
G Modulo - double Allgemeine Java-Themen 21
P Best Practice Wieso funktioniert der Modulo - Operator nicht? Allgemeine Java-Themen 2
T Modulo-Operator versagt bei zu großen Zahlen? Allgemeine Java-Themen 14
A Was berechnet Modulo denn da? Allgemeine Java-Themen 5
C Brauche Hilfe mit Modulo Strategie Allgemeine Java-Themen 2
R Modulo mit negativen Zahlen Allgemeine Java-Themen 8
B "Verschlüsselung" mit Passwort (XOR bzw. Modulo) Allgemeine Java-Themen 7
P große double Zahlen und modulo Allgemeine Java-Themen 8
I Problem mit Modulo Allgemeine Java-Themen 14

Ähnliche Java Themen

Neue Themen


Oben