source: flexoentity/org/FlexoEntity.org@ 37b5d11

Last change on this file since 37b5d11 was 37b5d11, checked in by Enrico Schwass <ennoausberlin@…>, 3 months ago

add guard for allowed_transitions

  • 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-Q251022-70F759@001D
74│ │ │ │ │ │
75│ │ │ │ │ └── State (Draft, Approved, Signed, Published, Obsolete)
76│ │ │ │ └──── Version
77│ │ │ └────────── Hash (3 bytes, 6 Stellen)
78│ │ └────────────────── Date (YYMMDD)
79│ └──────────────────── Entity type (Question)
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 eine Signatur und 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 Method "text_seed" implementieren, mit der
128der 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
142
143Das ist das Beispiel einer OptionQuestion, also einer Testfrage, wo mögliche Antworten enthalten sind
144
145 @property
146 def text_seed(self) -> str:
147 """Include answer options (and points) for deterministic ID generation."""
148 base = super().text_seed
149 if not self.options:
150 return base
151
152 joined = "|".join(
153 f"{opt.text.strip()}:{opt.points}"
154 for opt in sorted(self.options, key=lambda o: o.text.strip().lower())
155 )
156 return f"{base}::{joined}"
157
158** Lebenszyklus
159
160Der Lebenszyklus einer Entität folgt dieser Reihenfolge und ist nicht umkehrbar
161
162- Entwurf (DRAFT)
163- Genehmigt (APPROVED)
164- Unterschrieben (SIGNED)
165- Veröffentlicht (PUBLISHED)
166- Veraltet (OBSOLETE)
167
168Eine Entität, die bereits die Stufe Veröffentlicht erreicht hat, kann nicht in die Stufe
169(nur) Unterschrieben zurückkehren. Daher ist auch die Lebenszyklusstufe in der ID kodiert
170(letztes Symbol der FlexOID)
171
172Beispiele für Entitäten:
173
174- Testfrage
175- Fragenkatalog
176- Einstufungstest
177- Zertifikat
178
179Ein veröffentlichter Einstufungstest kann nur Fragen beinhalten, die ihrerseits die Stufe Veröffentlicht
180erreicht haben. Ein Zertifikat kann nur ausgestellt werden, wenn der passende Einstufungstest die Stufe
181Veröffentlicht hat. Das origin-Feld des Zertifikats sollte sinnvollerweise die ID des Tests enthalten.
182
183** Erhöhung der Versionsnummer oder neue ID
184
185Sobald - aus Gründen - eine neue ID vergeben werden muss, wird ggf. die Ursprungs-ID
186im Feld origin der neuen FlexoEntity gespeichert. So ist immer ein Suchen im Stammbaum möglich.
187
188AF-Q251022-70F759@001D
189│ │ │ │ │ │
190│ │ │ │ │ └── State (Draft, Approved, Signed, Published, Obsolete)
191│ │ │ │ └──── Version
192│ │ │ └────────── Hash (3 bytes, 6 Stellen)
193│ │ └────────────────── Date (YYMMDD)
194│ └──────────────────── Entity type (Question)
195└─────────────────────── Domain (e.g. Air force)
196
197
198Eine einfache Erhöhung der Versionsnummer (am Ende der ID) ist unter Umständen auch ausreichend,
199damit nicht zu häufig komplett neue IDs erzeugt werden müssen. Der Entscheidungsbaum dazu ist
200für das Projekt FlexoGrader recht umfangreich und soll hier nicht weiter besprochen werden.
201Da es aber im Hintergrund passiert und vom Endanwender nicht bemerkt wird, behindert der
202Mechanismus die Nutzung des FlexoGrader nicht.
203
204** Reifegrad
205
206Das Konzept und Design hat die Alpha-Phase verlassen, der Code ist aber noch deutlich Beta.
207RC1 etwa Anfang Dezember (nach meinem Urlaub). Änderungen an der FlexOID sind nicht mehr zu erwarten, beim API der FlexoEntity schon eher.
208
209Das Perfekte ist der Feind des Guten, aber ...
210
211Als Gegenbeispiel für unausgereiftes Design ist Pythons eingebaute datetime Bibliothek.
212Da könnte man ein Buch drüber schreiben. Halb Drama, halb Komödie.
213
214- dateutil, arrow, pendulum, maya, moment, delorean, pytz, zoneinfo + numpy/pandas
215
216** Lizenz
217
218Da ich die FlexoEntity-Bibliothek in meiner Freizeit entworfen und programmiert habe,
219bin ich alleiniger Urheber. Als Lizenz habe ich MIT gewählt, somit kann - unter Nennung
220des Urhebers - jeder damit machen, was er möchte
221
222Der FlexoGrader ist ein Bundeswehrprojekt, welches ich im Dienst programmiere und somit
223gehen die Nutzungsrechte uneingeschränkt auf den Dienstherren über.
224
225Das betrifft auch etwaige Folgeprojekte wie FlexoVault und FlexoDrill
Note: See TracBrowser for help on using the repository browser.