![]() |
Eindeutige ID aus einem String berechnen
Für die Lösung eines Problems benötige ich demnächst vermutlich etwas wie eine eindeutige ID, welche ich aus einem gegebenem String berechnen kann, der ohnehin schon eindeutig ist und nur einmal vorkommen kann. Die ID benötige ich aus diversen Gründen zusätzlich.
Die ID sollte wenn möglich nicht so lang sein wie MD5. Welche Möglichkeiten bleiben mir da noch? Mir stehen dafür unter anderem die Wolfgang Ehrhardt Komponenten zur Verfügung. Ich habe gerade CRC32 getestet. Aber ist das eindeutig genug?
Delphi-Quellcode:
function CRC32String(const Text: string): string;
var i: Integer; TextLen: Word; buf: array [0 .. 4095] of Byte; CRC: LongInt; ctx: TCRC_ctx; begin TextLen := Length(Text); for i := 1 to TextLen do buf[i - 1] := Byte(Text[i]); cm_Create(CRC32_Zip, nil, ctx); cm_Full(ctx, CRC, @buf, TextLen); Result := IntToHex(CRC, 8); end; |
AW: Eindeutige ID aus einem String berechnen
Hallo,
wenn es ein kann ist, nimm eine GUID und lass den arnen String in Ruhe. |
AW: Eindeutige ID aus einem String berechnen
Meinst du damit GUID := System.SysUtils.StringToGUID('test') ?
Laut fandom funktioniert das nur mit Strings im GUID Format ![]() |
AW: Eindeutige ID aus einem String berechnen
CRC ist eine Kontrollsumme, die es dir erlaubt, zu prüfen, ob ein String verändert wurde. CRCs sind nicht eindeutig, soll heißen, unterschiedliche Strings können gleiche CRCs haben.
Eine Hash-Funktion wäre eine Möglichkeit, aber da kann es auch zu Kollisionen kommen. Du kannst ein Lexikon anlegen + deine Strings nummerieren. Du kannst die Zahlenwerte der Zeichen nehmen und so eine Zahl erzeugen, die ist eindeutig (sogar eineindeutig, weil umkehrbar). Was magst denn machen, mit den IDs + was sind denn das für Strings? |
AW: Eindeutige ID aus einem String berechnen
Zitat:
Man kann zwar (theoretisch) für jeden gegebenen Satz von Strings ein Hash-Funktion finden, die innerhalb dieses Satzes für jeden der Strings einen eindeutigen Wert liefert, aber halt garantiert nur für Strings in dem vorgegebenen Satz, nicht für andere. Wozu brauchst Du denn die ID, und muss sie unbedingt aus dem String berechnet sein? Wenn beides eigentlich voneinander unabhängig ist und Du nur eine eindeutige ID brauchst ist eine GUID keine schlechte Wahl. |
AW: Eindeutige ID aus einem String berechnen
.. von wievielen Strings sprechen wir denn hier?
was zum Lesen: ![]() ![]() eine GUID ist nicht wesentlich kürzer als z.B. ein MD5 Hash Grüße Klaus |
AW: Eindeutige ID aus einem String berechnen
Ich brauche diese ID leider. MD5 und andere Hashes sind zu lang, da ich sonst Probleme mit zu langen Pfaden im Dateisystem bekommen könnte (nicht sicher).
Anders als aus einem String kann ich die ID auch nicht berechnen, da ich nur den String als Basisinformation habe. Anhand des Strings wird ein Verzeichnis angelegt. Der String wird vorher aber bereinigt und unzulässige Zeichen und andere besondere Zeichen entfernt. Es gibt Konstellationen, da bleibt am Ende das gleiche Ergebnis übrig. Deswegen würde ich gerne eine ID hinten dranhängen. Eine GUID würde ich gerne vermeiden da man so nie weiß welches Verzeichnis mit welcher GUID zu welchem Datensatz gehört. |
AW: Eindeutige ID aus einem String berechnen
Kannst du nicht einfach laufende Nummern verwenden und dir irgendwo ein Verzeichnis anlegen, in dem du dir die Zuordnung von String zu Nummer (= Name des Ordners) merkst?
|
AW: Eindeutige ID aus einem String berechnen
Jeder Datensatz hat intern einen Index, der sich aber bei jedem Programmstart ändern kann je nachdem, ob die Daten verändert wurden oder nicht. Im Normalfall ist davon auszugehen, dass sich die Daten bei jeder Sitzung mindestens einmal stark ändern. Leider nicht möglich mit einem Index.
Eine GUID wäre eventuell eine Lösung, wenn ich sie auch für jeden Datensatz in der Konfigurationsdatei mit ablege. Aber wie berechnet man eine korrekt formatierte GUID aus einem String? |
AW: Eindeutige ID aus einem String berechnen
Ob der MD5 HashWert in der Darstellung zu lang wird, hat doch nur etwas mit der Art der Darstellung zu tun.
Ein MD5-HashWert hat 128-bit. Diesen kann man Hexadezimal darstellen und erhält 32 Zeichen.
Code:
Zu lang? Dann hätten wir da noch eine Base64-Darstellung und erhalten von dem gleichen Wert
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
Code:
also 24 Zeichen (bzw. 22 denn die letzten beiden sind in diesem Falle immer gleich).
/////////////////////w==
Also, wie lang darf die errechnete ID aus dem String denn nun sein? PS: Wer jetzt einwenden möchte, dass in dem Base64 Zeichen vorkommen, die in einem Pfad nicht vorkommen dürfen, der hat Recht und ich überlasse es jedem selber dieses mit etwas Fantasie selber zu lösen. |
AW: Eindeutige ID aus einem String berechnen
So gesehen darf die ID so lang sein, bis das Dateisystem damit nicht mehr zurecht kommt. Der besseren Lesbarkeit aber dachte ich, je kürzer desto besser.
Ich glaube CRC32 reicht nachdem ich mir die Antwort von Victor Stoddard durchgelesen habe ![]() Und dann wäre da noch S. Lott ![]() |
AW: Eindeutige ID aus einem String berechnen
Zitat:
Kannst du den Originalstring nicht in einer kleinen Textdatei in dem jeweiligen Verzeichnis speichern? Dann könnte man solche Kollisionen zumindest erkennen und man hätte auch noch Zugriff auf den Originalstring. |
AW: Eindeutige ID aus einem String berechnen
Die Originalstrings werden bereits gespeichert und etwaige Duplikate schon behandelt.
Die einfachste Umsetzung wäre es das Verzeichnis in den jeweiligen MD5 Hash umzubenennen. Die Benutzerfreundlichkeit sinkt dann aber, weil ein Benutzer nicht mehr auf Anhieb sieht, welches Verzeichnis zu welchem Datensatz gehört. |
AW: Eindeutige ID aus einem String berechnen
Hast du mal probiert, ob es tatsächlich noch zu Kollisionen kommt, wenn du den CRC an den bereinigten String anhängst?
|
AW: Eindeutige ID aus einem String berechnen
Welche Zeichen können in den Strings denn vorkommen? Ggf. kann durch eine geschickte Kodierung daraus immernoch eindeutige aber deutlich kürzere Binärcodes erzeugen.
Beispiel: Wenn in den Strings nur die Großbuchstaben A-Z und die Ziffern 0-9 vorkommen, muss pro Zeichen eigentlich nur ein Wert von 0-35 abgespeichert werden, nicht von 0-255 (AnsiChar) oder gar mehr. Damit könnte man 256/36 = > 7 Zeichen in einem Byte abspeichern. Das ist natürlich nicht ganz ungefährlich, wenn Du nicht sicherstellen kannst, dass sich dieser Zeichenbereich nicht irgendwann ändert. Irgendwann kommt der Chef und sagt, "Wir lassen jetzt auch Kleinbuchstaben und Sonderzeichen zu.", und schon fliegt Dir der Algorithmus um die Ohren. Und erfahrungsgemäß wird der Programmierer bei solchen Entscheidungen nicht vorher gefragt. EDIT: Ich sehe gerade, dass es im Ergebnis um Verzeichisnamen geht. Damit kann man meine Idee nicht mehr so einfach umsetzen. |
AW: Eindeutige ID aus einem String berechnen
Zitat:
Zitat:
|
AW: Eindeutige ID aus einem String berechnen
Zitat:
Häng die ID an, das macht es auch nicht viel schlimmer als es eh schon ist. |
AW: Eindeutige ID aus einem String berechnen
Die Verzeichnisse werden jetzt nach einem MD5 Hash benannt. Das war die einfachste Umsetzung, ohne dass man noch an anderen Stellen Anpassungen machen muss die bei jeder kleinen Änderung hinfällig sind. Eigentlich hat ein Nutzer in diesen Daten nichts zu suchen, da alles über die Benutzeroberfläche und Business Logik erledigt wird.
|
AW: Eindeutige ID aus einem String berechnen
Bedenkt, dass Hashes ebenso nicht "eindeutig" sind, da zu jedem Hash auch unbegrenzt viele Strings gehören.
CRC32 ist nur deshalb keine Hashfunktion, weil du aus ihr den eigentlichen String sehr leicht wieder zurückgewinnen kannst. Dennoch hast du das gleiche Problem, wenngleich graduell geringer, auch bei Hashfunktionen (was diese von "Verschlüsselungen" unterscheidet). Es gibt so gesehen keine wirklich effiziente Möglichkeit, einen String in eine Zahl zu verwandeln, die wirklich eindeutig ist, ohne den vollen String selber zu beinhalten. Was du machen könntest, wäre noch folgendes (keine sichere Verschlüsselung!): Jedes ACSII-Zeichen befindet sich im Bereich von 0 bis 127. Solltest du also nur diese Zeichen brauchen, kannst du den zweiten teil des Bytes hinten weg lassen und mit dem nächsten Zeichen füllen. Ist aber auch nicht 100%-ig eindeutig, und vor allem nur für Zeichen des Standardzeichensatzes. |
AW: Eindeutige ID aus einem String berechnen
Ich klinke mich mal mit ein:
Der Threadersteller möchte eine eindeutige ID. CRC ist nicht dazu gedacht, eindeutige IDs zu generieren, da eine Kollision zu schnell herbeigeführt werden kann. Wikipedia gibt dazu als Beispiel die Wörter "buckeroo" und "plumless" an, die den gleichen CRC32-Wert besitzen. Die Wahrscheinlichkeit, dass der Threadersteller eine Kollision erhält, ist nicht unwahrscheinlich. *edit* Ich habe mir den ganzen Thread nochmal durchgelesen. Der Sinn des Ganzen erstreckt sich mir zwar nicht, aber von CRC würde ich absehen. Eine fortlaufende Nummer reicht da in meinen Augen als eindeutige Identifizierung. |
AW: Eindeutige ID aus einem String berechnen
Zitat:
|
AW: Eindeutige ID aus einem String berechnen
Zitat:
Und selbst dann ist dein Einwand doch vollkommen irelevant, weil das Problem doch trotzdem da ist: Es gibt mehrere Strings mit dem selben CRC-Wert. Also ist er nicht eindeutig, zumindest nicht in beide Richtungen. Somit für die Fragestellung nicht zu gebrauchen. Meine Aussage war ja nur, dass das bei Hashfunktionen halt eben nur graduell anders ist: Auch diese sind nicht eindeutig. Zur Sicherheit, und warum CRC für Hashes ungeeignet ist: Ja, natürlich bekommst du in beiden Fällen nicht das originale Word zurück. Ist aber doch vollkommen egal. Ein möglicher Hash reicht ja schon. Und da es bei CRC32 nun mal, wie von mir beschrieben, sehr leicht ist, diesen bzw. eins zu bekommen, ist es ungeeignet. Das heißt aber nicht, dass Hashfunktionen wie SHA128 "eindeutig" sind. Sie sind nur "eineutiger". |
AW: Eindeutige ID aus einem String berechnen
Verstehe nicht, was gegen "Durchnummerieren" spricht.
Und nur zum Verständnis: eine ![]() Sherlock |
AW: Eindeutige ID aus einem String berechnen
Zitat:
Dafür müsstest du ja eine
Delphi-Quellcode:
oder besser noch ein
TStringList
Delphi-Quellcode:
machen, und alles dort nochmal separat abspeichern.
TDictionary<String, Integer>
|
AW: Eindeutige ID aus einem String berechnen
Schon mal nach alternativen Hash Algorithmen als MD5 geschaut? Es gibt auch welche die nur 64 bit oder 80 bit lange Hashes erzeugen.
DEC beispielsweise enthält die Klasse THash_Sapphire, welche einen Hash Algorithmus umsetzt, der 64 bit Ergebnisse produziert. DEC ist via Github hier zu finden: ![]() |
AW: Eindeutige ID aus einem String berechnen
Zitat:
Macht insg. maximal 256 Ordner und darin dann viele Dateien, im Falle von git meistens mit SHA-1 (wird aber umgestellt glaub ich). Das Argument "Eigentlich hat ein Nutzer in diesen Daten nichts zu suchen, da alles über die Benutzeroberfläche und Business Logik erledigt wird." ist super, wenn eh alle in der Anwendung abrufbar ist, fummeln User in einer zugänglichen Datenstruktur nur zuviel rum. |
AW: Eindeutige ID aus einem String berechnen
Vielleicht ein wenig OT aber vielleicht doch relevant:
Zitat:
Das halte ich für nicht ganz ungefährlich. Vielleicht gefällt dem Benutzer ja der Verzeichnisname nicht und er ändert den. Die Konsequenzen für deine Anwendung kannst nur du abschätzen. Zitat:
Wenn deine Datensätze eine eindeutige ID haben, dann nutze diese. Wenn nicht, dann erzeuge dir welche. Damit bist du dein Problem sofort los, da du die ID für die Verzeichnisse nutzen kannst. Ich kenne deine Anwendung nicht, aber die Nutzung dieser Verzeichnisse sollte nur über die Anwendung passieren. Sobald ein Anwender darin rumpfuschen kann, wird das auch passieren. D.h.: Die Verzeichnisnamen müssen (besser dürfen) für den Anwender nicht lesbar sein. Sobald diese lesbar sind, werden diese "verbessert". EDIT: Zitat:
|
AW: Eindeutige ID aus einem String berechnen
Hier findest du noch Informationen zum Erzeugen eines 32-Bit Integer Hashes eines Strings:
![]() Schau dir dort mal die Funktion Murmur2 an. Kollisionen sind sicher möglich. Ist aber alles eine Frage der Wahrscheinlichkeit. |
AW: Eindeutige ID aus einem String berechnen
Noch eine Anmerkung zu den gebrochenen Hashes. Ich denke, das spielt für ihn keine Rolle. Da das nur unter Laborbedingungen passiert oder bei gezielten Angriffen. Dass sein Programm doppelte Hashes erzeugt, dürfte verschwindet gering sein. Wie viele Jahrzehnte hat man mit ihnen selbst bei sicherheitskritischen Anwendungen gearbeitet?
|
AW: Eindeutige ID aus einem String berechnen
Zitat:
|
AW: Eindeutige ID aus einem String berechnen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:22 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz