source: flexoentity/org/FlexoEntity.org@ 33be5a0

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

attempt to fix domain import for old exams - this is not a final fix

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