Halloween-Spaß mit flammendem Auge
Sein Blick durchbohrt Wolken, Schatten, Erde und Fleisch! Du weißt, wovon ich spreche. Ein großes Auge, lidlos, umrandet von Flammen.
• Gakken Worldeye Digital Globe Projector • Kostet ca. 160 € über eBay + Versand und Zoll bei Bestellung aus Japan (Stand 10/2017) • Technische Infos: hier • Tutorial Raspberry Pi + Worldeye = Animated eye • Tutorial Raspberry Pi3 + OpenCV • Noch ein Tutorial Raspberry Pi3 + OpenCV • Mein Pi_Eyes repository auf GitHub mit Erweiterung für animierte Iris und OpenCV Und für die Sprüche von Sauron lädt man sich Shadow of Mordor über Steam runter (~ 42 GB), entpackt die Sounddateien mit dem Ravioli-Game-Tool (ja, das heißt wirklich so), hört sich die 14190(!) Wave-Dateien durch und kopiert sich was man braucht. Da die Dateien urheberrechtlich geschützt sind, sollte das naheliegenderweise ausschließlich für private Zwecke geschehen.
Frühförderung im Computer-Club
Holpriger Start: Star Trek Discovery
- Ein phantasieloses Intro, das genauso gut ein Werbeclip für irgendein ein CAD-Tool sein könnte. Laaangweiliiig!
- Kurios: das namensgebende Raumschiff taucht in den ersten beiden Folgen kein einziges Mal auf / wird nicht mal erwähnt.
- Eine sich ewig hinziehende Eröffnungssequenz auf einem Wüstenplaneten, die rein überhaupt gar nichts mit der späteren Handlung zu tun hat. Wozu?
- Bat'leths, die nicht wie Bat'leths aussehen. Hättet ihr doch nur jemanden gefragt!
- Ein Sternenflottenschiff (USS Shenzhou), dessen Brücke nicht auf Deck 1 ist sondern unten an der Untertassensektion hängt. What!?
- Ein Computer der Gefängniszelle des Schiffs, der sich überreden lässt dich freizulassen, wenn du nur genug jammerst. Ja, ernsthaft.
- Jede Menge nervige Lens Flares in den Weltraum-Szenen.
- Und, und, und ...
Warum man fremdem Code nicht trauen darf
- int a = 0;
- printf("Der Wert von Variable 'a' ist %d.\n", a);
- BoeseFunktion(4711);
- a = 1;
- printf("Der Wert von Variable 'a' ist jetzt %d.\n", a);
BoeseFunktion()
dass die Ausgabe in der zweiten Zeile Der Wert von Variable 'a' ist jetzt 0.lautet? Selbst wenn 'a' nur lokal der Main-Funktion bekannt ist? Ich sage ja:
- void BoeseFunktion(int tmp) {
- int* pointer;
- pointer = &tmp - 1;
- *pointer = *pointer + 8;
- }
pointer = &tmp - 1;
hole mich mir einen Zeiger auf den ersten Funktionsparameter und reduziere die Adresse um 1. Auf x86-Systemen bin ich nun an der Rücksprungadresse von BoeseFunktion() auf dem Stack.
So sieht das im Speicher aus:
Und mit *pointer = *pointer + 8;
erhöhe ich anschließend die Rücksprungadresse um 8 Byte, was gerade soviel ist um das a = 1;
in main() zu überspringen.
Solches Gehacke mit Pointer-Arithmetik ist natürlich sowieso pfui. Aber was uns dieses Beispiel eigentlich lehren soll ist, dass man fremden Funktionen nicht trauen soll.
Es könnte schließlich sein, dass ich sie geschrieben habe... 😉Schadensabwehr
Aber wie bekommt man nun das Problem in den Griff, dass Fremdcode, den man in so gut wie jedem Projekt findet, unbeabsichtigt oder beabsichtigt Unfug anstellt und Daten oder die Programmausführung beeinträchtigt? Da gibt es mehrere Möglichkeiten. Unter anderem:- Logische Programmablaufkontrolle Man stelle sich vor, jede eigene Funktion meldet sich bei ihrem Aufruf an einer zentralen Instanz mit einem eindeutigen Key. Die zentrale Instanz überprüft dann anhand einer Tabelle ob es in Ordnung ist, dass Funktion3 nun auf Funktion2 folgt oder nicht. Bringt fremder Code - zum Beispiel eine defekte DLL - den Ablauf durcheinander so wird dies schnell aufgedeckt. Voraussetzung für ein solches System ist natürlich eine deterministische Reihenfolge der Funktionsaufrufe.
- Datenredundanz Zuerst einmal sollten alle Daten, die irgendwie wichtig sind, redundant vorliegen; am besten redundant-invers. Das heißt, es gibt nicht eine Variable 'a', sondern z.B. 'unsigned char u8VentilSollwert' und 'unsigned char u8VentilSollwertInvers'. Das hat nicht nur einen eingängigeren Namen als 'a' sondern informiert uns auch gleich noch über das Präfix u8, dass es eine unsigned 8-Bit-Variable ist mit Wertebereich von 0..255. In der einen steht dann z.B. 1 (binär 0000 0001) und in der anderen das Gegenteil, also 254 (1111 1110). Vor Verwendung wird jedes Mal geprüft, ob die beiden Variablen noch Bit-invers sind und falls nicht mit Fehlermeldung abgebrochen.
- Datensicherung Wenn die Daten umfangreicher sind, gibt es die Möglichkeit sie mit einer Checksumme zu sichern. Wird die Checksumme oder die Daten beschädigt, so fällt dies auf, sobald man die Checksumme nachrechnet und mit dem Prüfwert vergleicht.