source: flexoentity/org/FlexoEntityTalk.org@ d7499ca

Last change on this file since d7499ca was d7499ca, checked in by Enrico Schwass <ennoausberlin@…>, 7 weeks ago

Signature support for Linux and MacOS added

  • Property mode set to 100644
File size: 10.6 KB
Line 
1* Tech-Talk - Hashes / IDs / Lebenszyklen / FlexoEntity
2:PROPERTIES:
3:CUSTOM_ID: hashes-ids-lifecycle
4:END:
5
6** Was ist ein Hash?
7
8Ein Hash ist ein hoffentlich eindeutiger "Fingerabdruck" für Daten, der
9sich aus eben diesen Daten über den Algorithmus einer Hash-Funktion errechnet.
10
11Die Eingabedaten bezeichnet man als Seed, das Ergebnis als Digest.
12
13Man gibt die Saat (das Futter) an die Hashfunktion zum Zerkauen/Zerkleinern (Hashen),
14das wird verdaut, nebenbei noch gewürzt (Salt) und kommt als Digest wieder heraus.
15Die Länge der Ausgabe ist fest.
16
17** Ein wichtiger Punkt
18
19Wichtig ist auch zu verstehen, dass Hashes sogenannte "One-Way-Funktionen" sind.
20Das heißt, man kann das Hashing nicht einfach umkehren, um das ursprüngliche Objekt wiederherzustellen.
21Ein Hash ist also eine Einbahnstraße: Er dient nur dazu, die Daten zu repräsentieren,
22aber man kann nicht vom Hash auf die originalen Daten zurückrechnen.
23Aus Kacke kann man kein Essen zaubern.
24
25** Was ist kein Hash?
26
27Die ISBN identifiziert ein Buch eindeutig. Sie ist nicht das Buch selbst, sondern eher ein
28Identifier (eine geordnete Nummer mit Prüfziffer). Sie ist aber kein Hash, weil sie nicht
29aus dem Inhalt des Buches berechnet wird. Ähnliches gilt für die IBAN
30
31|-------------------------+---------------------------+-------------------------------------|
32| Merkmal | Hash | Identifier (z. B. ISBN, IBAN, UUID) |
33|-------------------------+---------------------------+-------------------------------------|
34| Abhängig vom Inhalt | ja | nein |
35| Ziel | Integrität / Vergleich | Identität / Referenz |
36| Länge | fix z. B. 32 Hex-Zeichen | frei definierbar |
37| Zufällig oder berechnet | deterministisch berechnet | oft generiert oder vergeben |
38|-------------------------+---------------------------+-------------------------------------|
39
40** Warum verwenden wir Hashes?
41
42Hashes sind super praktisch, weil sie uns eine Menge Zeit und Rechenleistung sparen.
43Anstatt zwei große Dateien oder ganze Bücher direkt miteinander zu vergleichen,
44vergleichen wir einfach ihre Hashes. Wenn die Hashes gleich sind, wissen wir,
45dass die Daten sehr wahrscheinlich identisch sind. Wenn sie unterschiedlich sind,
46hat sich etwas geändert. Das spart enorm viel Aufwand.
47
48** Beispiele für den Einsatz von Hashes
49
50- **Passwort-Hashes**: Wenn du ein Passwort eingibst, wird oft nur der Hash gespeichert, nicht das
51 eigentliche Passwort. So bleibt es sicher, selbst wenn jemand die Datenbank stiehlt.
52
53 Beispiel aus der /etc/shadow-Datei
54
55root:$6$tsicHaoV3Q$YtAbiIvrHGXFtAJYz9tcEYWHXiGVQ40sJAgzPAbc57lIq9jH8eYjWXwctSW6YQnrMznRFcm6yXLnnY9mHhso20
56enno:$6$sdygzfEgx0$YpaZJMQdkZgxGPclphz6RojqNG.PSNEq1oIHRP4kvZRN2iuS5MQrxt0nCkrYQIcpDGyohrb1o0S/GkWrFriWL1
57
58Der Hash ist länger als das Passwort. Das dient der Sicherheit, weil man zwar nicht zurückrechnen,
59wohl aber vorwärtsrechnen kann. Hash-Funktionen sind deterministisch.
60Bei Linux-Passworteinträgen hat man hier $6$ den Hashalgorithmus kodiert, im daraufolgendem $.....$ das Salz
61und im Rest den eigentlichen Hash kodiert
62
63- **Git-Commits**: In Versionskontrollsystemen wie Git werden Hashes benutzt, um jeden Schwung an
64 Änderungen mit einer eindeutigen Kennung zu versehen
65
66- **URL-Shortener: hash("https://example.com") → 8a3f12
67
68** FlexOID
69
70Die FlexOID ist eine Mischform. Sie selbst ist ein Identifier, der als Bestandteil aber einen Hash
71enthält, um möglichst eindeutig, aber nicht zu lang zu sein.
72
73AF-I251022-70F759@001D
74│ │ │ │ │ │
75│ │ │ │ │ └── State (Draft, Approved, Signed, Published, Obsolete)
76│ │ │ │ └──── Version
77│ │ │ └────────── Hash (6 bytes, 12 Stellen)
78│ │ └────────────────── Date (YYMMDD)
79│ └──────────────────── Entity type (ITEM)
80└─────────────────────── Domain (e.g. Air force)
81
82In der ersten Variante der FlexOID habe ich mich mit einem 6-stelligen Hash zufrieden gegeben,
83weil das einfach lesbarer ist. Warum reicht das nicht?
84
85** Das Geburtstags-Paradoxon
86
87Der obige 3-Byte Hash liefert mir etwas über 16 Millionen unterschiedlich Varianten.
88Das klingt viel. Ist es aber nicht. Wieviele Schüler müssen nacheinander die Klasse
89betreten bis sich zwei finden, die mit mehr als 50 Prozent Wahrscheinlichkeit am gleichen
90Tag Geburtstag (also ein identisches Merkmal) haben?
91
92** Lösung
93
94Ab 23 Schülern beträgt die Wahrscheinlichkeit 50 % (näherungsweise Wurzel 365 Tagen)
95
96Bei 47 Schülern beträgt die Wahrscheinlichkeit bereits 95 Prozent
97
98Unsere 3 Bytes ergeben zwar 16.000.000 mögliche Varianten - im Gegenzug zu den 365 Tagen im Jahr
99aus dem Geburtstagsbeispiel - aber da die Wahrscheinlichkeit zur Kollision hier bei
100etwa Wurzel 16 Mio. liegt, bekommt man bereits bei 4000 Neuzugängen die ersten
101Übereinstimmungen im Hash.
102
103Der Hash ist also nicht gut genug, weil man sehr schnell und sehr häufig, diese
104Übereinstimmungen feststellen und behandeln müsste, wenn man weiterhin eindeutige
105Zuordnungen treffen will.
106
107Wenn man die Ausgabe der Hashfunktion auf 6 Bytes erweitert, kommen die ersten Kollisionen
108erst bei etwa 20 Mio erzeugten Hashes (Fingerabdrücken) und die kann man dann ohne
109Einbußen gesondert behandeln (Salzen), weil es so selten passiert.
110
111Übrigens, wenn man beim Menschen den Daumenabdruck nimmt und sich dabei auf 12 Merkmale
112beschränkt und sehr lockere Toleranzen ansetzt (was man in der Praxis nicht macht),
113hat man bereits nach 14000 Menschen eine Übereinstimmung. Bei 24 Merkmalen und sehr
114lockeren Toleranzen, hat man bei etwa nach 9 Mio. Menschen eine ungefähre Übereinstimmung.
115Da muss die Polizei schon sehr schlampig arbeiten, damit man fälschlicherweise beschuldigt wird.
116Die Zahlen in der Realität sind sogar noch deutlich höher.
117
118** FlexoEntity
119
120Nun haben wir gesehen, dass wir mit der FlexOID (mit 6-Byte Hash) sehr viele unterschiedliche
121Dinge eindeutig bestimmen können. Da unsere FlexOID erstmal nur eine Zeichenfolge ist,
122brauchen wir etwas das damit umgehen kann und was dafür verantwortlich ist. Das ist die FlexoEntity.
123
124Sie beinhaltet zusätzlich ein Origin-Feld, wo festgehalten wird, woher diese
125Entität stammt (beispielsweise aus einer Hashkollision oder einer Änderung an den weiteren Daten)
126
127Jede Klasse, die von FlexoEntity erbt, muss zwingend die Methode "text_seed" implementieren,
128mit der der Algorithmus einer Hash-Funktion gefüttert wird, aus der dann der 6-Byte Hash herauspurzelt.
129Hashfunktionen sind z.B. MD5, SHA1, SHA256 oder wie von mir genutzt: Blake2s.
130Die Mathematik dahinter ist recht aufwändig, aber wer sich mal einlesen möchte
131
132- Hashing in Smalltalk: Theory and Practice von Andres Valloud
133
134Damit die Hash-Funktion genug Eingabedaten pro Entity hat, muss man sich überlegen, welche Merkmale
135einer Entität man durch "text_seed" übermittelt.
136
137** text_seed
138
139Man kann beliebige Klassen von FlexoEntity ableiten und erhält ohne Aufwand die Funktionalität
140zur eindeutigen Identifizierung und zur Lebenszyklus-Verwaltung
141
142Das ist das Beispiel einer ChoiceQuestion, also einer Testfrage, wo mögliche Antworten enthalten sind
143
144 @property
145 def text_seed(self) -> str:
146 """Include answer options (and points) for deterministic ID generation."""
147 base = super().text_seed
148 if not self.options:
149 return base
150
151 joined = "|".join(
152 f"{opt.text.strip()}:{opt.points}"
153 for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
154 )
155 return f"{base}::{joined}"
156
157** Lebenszyklus
158
159Der Lebenszyklus einer Entität folgt dieser Reihenfolge und ist nicht umkehrbar
160
161- Entwurf (DRAFT)
162- Genehmigt (APPROVED)
163- Unterschrieben (APPROVED_AND_SIGNED)
164- Veröffentlicht (PUBLISHED)
165- Veraltet (OBSOLETE)
166
167Eine Entität, die bereits die Stufe Veröffentlicht erreicht hat, kann nicht in die Stufe
168(nur) Unterschrieben zurückkehren. Daher ist auch die Lebenszyklusstufe in der ID kodiert
169(letztes Symbol der FlexOID)
170
171Beispiele für Entitäten:
172
173- Testfrage
174- Fragenkatalog
175- Einstufungstest
176- Zertifikat
177
178Ein veröffentlichter Einstufungstest kann nur Fragen beinhalten, die ihrerseits die Stufe Veröffentlicht
179erreicht haben. Ein Zertifikat kann nur ausgestellt werden, wenn der passende Einstufungstest die Stufe
180Veröffentlicht hat. Das origin-Feld des Zertifikats sollte sinnvollerweise die ID des Tests enthalten.
181
182** Erhöhung der Versionsnummer oder neue ID
183
184Sobald - aus Gründen - eine neue ID vergeben werden muss, wird ggf. die Ursprungs-ID
185im Feld origin der neuen FlexoEntity gespeichert. So ist immer ein Suchen im Stammbaum möglich.
186
187AF-Q251022-70F759@001D
188│ │ │ │ │ │
189│ │ │ │ │ └── State (Draft, Approved, Signed, Published, Obsolete)
190│ │ │ │ └──── Version
191│ │ │ └────────── Hash (3 bytes, 6 Stellen)
192│ │ └────────────────── Date (YYMMDD)
193│ └──────────────────── Entity type (Question)
194└─────────────────────── Domain (e.g. Air force)
195
196
197Eine einfache Erhöhung der Versionsnummer (am Ende der ID) ist unter Umständen auch ausreichend,
198damit nicht zu häufig komplett neue IDs erzeugt werden müssen. Der Entscheidungsbaum dazu ist
199für das Projekt FlexoGrader recht umfangreich und soll hier nicht weiter besprochen werden.
200Da es aber im Hintergrund passiert und vom Endanwender nicht bemerkt wird, behindert der
201Mechanismus die Nutzung des FlexoGrader nicht.
202
203** Reifegrad
204
205Das Konzept und Design hat die Alpha-Phase verlassen, der Code ist aber noch deutlich Beta.
206RC1 etwa Anfang Dezember (nach meinem Urlaub). Änderungen an der FlexOID sind nicht mehr zu erwarten, beim API der FlexoEntity schon eher.
207
208Das Perfekte ist der Feind des Guten, aber ...
209
210Als Gegenbeispiel für unausgereiftes Design ist Pythons eingebaute datetime Bibliothek.
211Da könnte man ein Buch drüber schreiben. Halb Drama, halb Komödie.
212
213- dateutil, arrow, pendulum, maya, moment, delorean, pytz, zoneinfo + numpy/pandas
214
215** Lizenz
216
217Da ich die FlexoEntity-Bibliothek in meiner Freizeit entworfen und programmiert habe,
218bin ich alleiniger Urheber. Als Lizenz habe ich MIT gewählt, somit kann - unter Nennung
219des Urhebers - jeder damit machen, was er möchte
220
221Der FlexoGrader ist ein Bundeswehrprojekt, welches ich im Dienst programmiere und somit
222gehen die Nutzungsrechte uneingeschränkt auf den Dienstherren über.
223
224Das betrifft auch etwaige Folgeprojekte wie FlexoVault und FlexoDrill
Note: See TracBrowser for help on using the repository browser.