29.09.2016

Häufigkeiten von Würfelsummen - kleines Rätsel

Ich bin ein typischer Informatiker - wenn irgendwo ein Rätsel, Denksportaufgabe o.ä. abgedruckt ist, muss ich es probieren. Zuerst denke ich kurz darüber nach, ob es eine offensichtliche Lösung gibt, und da ich sehr ungeduldig bin, geht das nicht lange gut ;)

Danach denke ich darüber nach, wie ich die Aufgabe mit dem Rechner lösen kann - auch das Nachdenken über eine algorithmische Lösung ist schließlich Denksport ;)

Kürzlich fragte die "Spektrum der Wissenschaft" nach der Häufigkeitsverteilung beim Würfeln mit drei Würfeln. Das ist ein nettes Beispiel für eine Anfängeraufgabe, und natürlich versuchte ich mich damit, das "Problem" in perl zu lösen. Ich liebe perl, perl ist cool, genauso wie Fliegen cool sind ;)

Also zurück zur Aufgabe: welche Würfelsumme ist beim Würfeln mit drei Würfeln am häufigsten?

Der offensichtliche Ansatz ist eine dreifach geschachtelte Schleife, d.h. dreimal von 1 bis 6 zählen, Summe bilden und diese Summe (die zwischen 3 und 18 liegen kann) als Index verwenden, um in einem Array einen Zähler für diese Summe zu erhöhen.

Bei dieser Aufgabe kann man einige coole Features von perl gut zum Einsatz bringen, nämlich Arrays und einige sehr bequeme Funktionen und Operatoren, um mit Arrays umzugehen.

Natürlich will ich das kleine perl-Programm nicht einfach so hier in's Blog werfen, sondern ein paar der Besonderheiten von perl  ausführlicher kommentieren.

Zunächst verwende ich für das Zählen der Häufigkeiten ein assoziatives Array %sum, bei dem die Indizes beliebige Strings sein können, und kein Array mit numerischen Indizes. Das mag zunächst unnötig umständlich wirken, aber es erspart mir später einige Fallunterscheidungen, weil ich mir vorgenommen habe, Funktionen zu verwenden, die wenig bekannt sind. Aber natürlich gilt wie immer der perl-Leitsatz "there's more than one way to do it", und man kann die Aufgabe auch lösen, wenn man ein Array @sum verwendet.

Das Progrämmchen besteht aus drei Teilen: Variablendeklaration, Berechnung und Ausgabe. Die Kommentare unten markieren diese drei Teile. Ganz unten ist der vollständige Code zu finden, und hier im Text jeder Teil einzeln.

# Variablendeklaration
my %sum;


Wie schon beschrieben, wird bei der Berechnung einfach die Summe der drei ineinander geschachtelten Laufvariablen (i1, i2, i3) berechnet und als Index in das Array verwendet. Der auch aus C bekannte "++"-Operator addiert eins zum adressierten Array-Element. Die Schreibweise für die Schleifen finde ich besonders elegant: der perl-Operator ".." erzeugt eine Liste (oder auch Array genannt) von .. bis. Das funktioniert übrigens nur sauber in der Aufwärts-Richtung, es gibt grenzwertige Situationen, in denen man überrascht wird, wenn das bis kleiner ist als das von, also obacht hier!

# Berechnung
foreach my $i1 (1..6) {
    foreach my $i2 (1..6) {
        foreach my $i3 (1..6) {
            ++$sum{$i1+$i2+$i3};
        }
    }
}


Bei der Lösung solcher Aufgaben sollte man sich vorher überlegen, ob man den "brute force"-Ansatz wählt und einfach alle Varianten durchprobiert oder ob es Optimierungsmöglichkeiten gibt, mit denen man die Komplexität reduzieren kann. Bei drei Schleifen von 1 bis 6, mithin also 216 Schleifendurchläufen, ist das Programm selbst auf einem C-64 noch zu meinen Lebzeiten beendet ;)

# Ausgabe
print join("\n",
           map { sprintf("% 3d",$_) . " => $sum{$_}" }

               sort { $sum{$b} <=> $sum{$a} }
                    keys(%sum)
      ),"\n";


Bei der Ausgabe der Ergebnisse habe ich tief in die Trickkiste gegriffen und alles in einen einzigen "print"-Befehl gepackt. Dieser Befehl bekommt als Parameter das Ergebnis des "join"-Kommandos und hintendran wird noch ein einzelnes "\n", also ein Zeilenumbruch gehängt. Die Einrückungen habe ich so gewählt, dass man genau sieht, was zusammengehört.

print join("\n",
           map { sprintf("% 3d",$_) . " => $sum{$_}" }
               sort { $sum{$b} <=> $sum{$a} }
                    keys(%sum)
      ),"\n";


Der "join"-Befehl selbst nimmt zwei Parameter: das Verbindungszeichen "\n" und ein Array von Strings (man kann in perl alles als String verwenden, selbst Zahlen - es gibt keine strikte Unterscheidung, wie man ein "skalares Element" verwenden darf).

map { sprintf("% 3d",$_) . " => $sum{$_}" }
   
sort { $sum{$b} <=> $sum{$a} }
         keys(%sum)


Das "Array von Strings", das "join" bekommt, wird von einem "map"-Befehl dynamisch erzeugt. "map" ist eigentlich ein versteckter Schleifenoperator und erzeugt aus einer Funktion und einem Array als Parameter wiederum ein Array. Dies ist eines der faszinierenden Features von perl, die ich oben erwähnt hatte: "map" nimmt als Parameter eine namenlose Funktion, die man in {} schreibt.

In dieser Funktion, genau wie im folgenden Befehl "sort" gibt es Pseudo-Variablen, die nur innerhalb dieser Funktion benutzbar sind. Bei "map" ist es die Variable "$_", die das aktuell bearbeitete Array-Element beinhaltet. Dieses Element ist der Index des Arrays und bedeutet hier eine spezielle Würfelsumme. Mit "sprintf" formatiere ich diese Zahl rechtsbündig, dahinter hänge ich mit dem Stringoperator "." noch ein bißchen Schmuck als Trennzeichen an und danach noch die tatsächliche Anzahl an Möglichkeiten, diese Würfelsumme zu werfen.

sort { $sum{$b} <=> $sum{$a} } keys(%sum)

Jetzt kommt noch ein weiteres cooles Feature von perl: es gibt einen eingebauten Befehl zum Sortieren von Arrays, und diesem Befehl kann ich wiederum in einer namenlosen Funktion mitgeben, wie ich die Sortierung wünsche. Da ich beim Sortieren immer zwei Elemente vergleichen muss, liefert mir perl bequemerweise zwei Pseudovariablen, die mit "$a" und "$b" bezeichnet werden. Diese Variablen sind nur innerhalb dieses "sort"-Befehls bekannt und beeinflussen eventuell "außerhalb" deklarierte Variablen "$a" und "$b" nicht!

Sortiert wird absteigend nach der Häufigkeit, mit der dieser Würfelwurf vorkommen kann, also nach dem Inhalt des Arrays an dieser Stelle, und der "<=>"-Operator erzählt mir, welcher der beiden Werte kleiner bzw. größer ist. Dies ist ein sogenannter "ternärer" Operator, der mir je nach Vergleichsergebnis -1, 0 oder 1 liefert (also drei mögliche Ergebnisse, deshalb "ternär").

Solche verketteten Ausdrücke in perl muss man also von hinten nach vorne lesen, damit man den Sinn versteht.

Nochmal aus dieser Sichtweise betrachtet: ich sortiere das Array nach der Häufigkeit und übergebe das sortierte Array an "map", um dort die einzelnen Array-Elemente hübsch lesbar zu machen. Mit "join" verknote ich alle diese aufgehübschten Array-Elemente, so dass "print" einen einzelnen String ausgeben kann.

Und dies ist das gesamte Skript ohne Erklärungen dazwischen:

#!/usr/bin/perl -w


# Variablendeklaration

my %sum;

# Berechnung

foreach my $i1 (1..6) {
    foreach my $i2 (1..6) {
        foreach my $i3 (1..6) {
            ++$sum{$i1+$i2+$i3};
        }
    }
}
 

# Ausgabe
print join("\n",
           map { sprintf("% 3d",$_) . " => $sum{$_}" }
               sort { $sum{$b} <=> $sum{$a} }
                    keys(%sum)
      ),"\n";



[Update 20160930: Schleife von for auf foreach geändert, Einrückungen bei print zur Verdeutlichung]

16.09.2016

Linux kernel patch update skript

Ich bin ein großer Freund von "Selber machen" - zumindest am Computer. In der echten Welt hab ich eher so zwei linke Hände ;)

Das resultiert darin, dass mein Server zuhause mit einem selbst gelöteten Linux arbeitet, nämlich mit "Linux from Scratch", bei dem man alle Pakete selbst als Quelltext herunterlädt und installiert.

Zuerst hatte ich mal SuSE verwendet, aber die Paketverwaltung und die Abhängigkeiten waren mir dann zu viel geworden. Also dann: alles selbst kompilieren und genau sehen, welche Abhängigkeiten unbedingt nötig sind und welche nicht. Bei vorgefertigten Linux-Distributionen wird eigentlich immer das maximale Kunstwerk installiert, und genau das wollte ich nicht.

Diese DIY-Methode hat auch den Vorteil, dass man immer genau die gewünschte Version von Software hat, z.B. beim Kernel auch immer die neueste, die dann z.B. aktuelle Hardware unterstützt.

Ich will hier ein kleines Skript vorstellen, das ich mir vor längerer Zeit als Hilfsmittel gebastelt habe, um den Linux-Kernel immer auf dem aktuellen Stand zu halten.

Das Skript lädt eine neue Version in Form der Differenzdatei herunter, wendet dann diesen einen oder auch mehrere Patches an und speichert das Ergebnis wieder als neuestes Kernelpaket. Das kann man dann auch gleich kompilieren und dem Bootload unterjubeln (dazu hab ich ein separates Skript).

In blau hab ich ein paar Bemerkungen dazugeschrieben; das Skript ist aber eigentlich selbsterklärend - finde ich ;)

#!/bin/sh -e

msg() { echo "$*" 1>&2; }
err() { msg "$*"; exit 1; }


# dies ist die Basisversion des Kernels
base="${1:-4.7}"
# "von" Version
old="${2:-0}"

# "nach" Version
new="${3:-4}"
v="${base}.${old}"
latest="linux-${base}.${new}"

# die Files heißen 4.7 und nicht 4.7.0
test "${old}" = "0" && v="${base}"
test "${new}" = "0" && latest="linux-${base}"



url="https://cdn.kernel.org/pub/linux/kernel/v4.x"
wget="wget -q --no-check-certificate"

kl="linux-${base}.${new}"
ext="xz"
source="/sources"

# nix mehr zu tun, schon da
test -f "${kl}" && err "# Kernel ${kl} exists"

msg "unpack linux-${v}"
work=$(mktemp -d -p "${source}")
cd "${work}"
tar xf "${source}/linux-${v}.tar.${ext}"
mv "linux-${v}" "${latest}"

# wenn der alte Kernel 0 ist, reicht der neueste Patch allein
if [ "${old}" = "0" ]
then
    patch="patch-${base}.${new}.${ext}"
    test -f "${patch}" || ${wget} "${url}/${patch}"
    test -f "${patch}" || err "! download ${patch} failed"
    msg "apply ${patch}"
    xz -cd "${patch}" | patch -d "${latest}" -Nstp1
else

# ansonsten jeden patch von x nach x+1 holen
    while [ "${old}" -lt "${new}" ]
    do
        next=$(expr "${old}" + 1)
        ipatch="patch-${base}.${old}-${next}.${ext}"
        test -f "${ipatch}" || ${wget} "${url}/incr/${ipatch}"
        test -f "${ipatch}" || err "! download ${ipatch} failed"
        msg "apply ${ipatch}"
        xz -cd "${ipatch}" | patch -d "${latest}" -Nstp1
        rm -f "${ipatch}"
        old="${next}"
    done
fi
rc="${?}"

if [ ${rc} -eq 0 ]
then
    msg "pack ${latest}"
    egrep "^(VERSION|PATCHLEVEL|SUBLEVEL) = " "${latest}"/Makefile 2>/dev/null
    tar cf - "${latest}" | xz -9 > ../"${latest}.tar.${ext}"
    msg "cleanup tmp"
    cd ..
    rm -fr "${work}"
else
    err "! patch failed, rc=${rc}"
fi

14.09.2016

Flash-Update auf Version 23

Mir fehlen langsam die Worte, wie die Versionsnummern inflationär in Höhen klettern. Google hat es mit Chrome vorgemacht, aus irgendwelchen Gründen macht es Mozilla mit Firefox und Thunderbird nach, und jetzt beschleunigt Adobe die Nummerierung des Flashplayers genauso.

Und weil mir die neuen Worte fehlen, nehme ich immer den alten Blogartikel, nur die Versionsnummern und die Links ändern sich ;)

Oha, am Security Bulletin merke ich, dass ich 22.0.0.211 verpasst habe, ich kannte nur .209. Naja. Sorry ;-)

Einen Hinweis muss ich aber nun doch noch einbauen: ab Ende Januar 2016 gibt  es keine freien Downloads der Installationsdateien mehr. Genaue Modalitäten sind noch nicht bekannt, Adobe hat nur bekannt gegeben, dass die Downloadlinks über die "distribution3.html"-Seite nicht mehr zur Verfügung stehen werden und man eine Adobe-ID und eine Business-Lizenz benötige.

Grade erst Version 16 (siehe meinen älteren Blogartikel von November 2015) und 17 (hier) und 18 (hier im Blog) und 19 (hier im Blog) und 20 (hier im Blog) und 21 (hier im Blog) und 22 (hier im Blog), jetzt schon 23 (mittlerweile zählt wohl auch ein Major release nicht mehr zu den besonders erwähnenswerten Ereignissen bei Adobe?). Wer sich selbst auf dem Laufenden halten will, kann das Blog des Security-Teams bei Adobe lesen oder als RSS abonnieren.

Wie üblich in ihrem freundlichen Service-Blog die passende Automation zum Herunterladen und Installieren. Falls ein Proxy verwendet wird, das "rem" bzw. "#" entfernen und eigene Proxy-Adresse eintragen.

Das Tool wget wird bei Windows noch benötigt wie hier beschrieben. Bei Linux sollte es schon vorhanden sein, da es von vielen anderen Programmen intern verwendet wird.

Für Windows wie üblich beide Varianten, ActiveX und Netscape Plugin (Achtung übrigens, Firefox wird demnächst das NPAPI komplett abschaffen - mal sehen, was Adobe und Flash dann machen).
@echo off

rem set http_proxy=http://192.168.100.100:3128/
set VNP=
23.0.0.207
set VAX=
23.0.0.207
set V=23
set H=fpdownload.macromedia.com
set P=/get/flashplayer/current/licensing/win
set AX=install_flash_player_%V%_active_x.exe
set NP=install_flash_player_%V%_plugin.exe

wget http://%H%%P%/%AX% -O flash-%VAX%_ax.exe
.\flash-%VAX%_ax -install
wget http://%H%%P%/%NP% -O flash-%VNP%_np.exe
.\flash-%VNP%_np -install

Für Linux 64 bit rpm (als root ausführen oder "sudo rpm" schreiben) gibt es nach wie vor "nur" Version 11, aber zur Abwechslung haben sich der Downloadlink und der Dateiname für .rpm geändert. Für .tar.gz-Format ist immer noch der erste Downloadlink gültig, deshalb belasse ich beide im Skript.
#!/bin/sh

# http_proxy=http://192.168.100.100:3128/

VL=11.2.202.644
H=fpdownload.macromedia.com

PL1=/get/flashplayer/current/licensing/linux
PL2=/get/flashplayer/pdc/${VL}


DL() { wget -N "$1/$2"; mv "$2" "$3"; }

echo Linux 64 bit rpm ...
DL http://${H}${PL2} \
   flash-plugin-${VL}-release.x86_64.rpm \
  
flash-${VL}.x86_64.rpm
rpm -F --force
flash-${VL}.x86_64.rpm
[20160914: Security-Bulletin von Adobe]
[20161012: Security-Bulletin von Adobe]
[20161026: Security-Update von Adobe]
[20161109: Security-Update von Adobe

13.09.2016

Ersatzteile für ältere Autos

Wie versprochen folgt heute nun der zweite Teil meines Berichts über das derzeitige Auto-Desaster. Wie schon erzählt, war die Ersatzteilbeschaffung für die Familienkutsche Fiat Ulysse nicht ganz einfach.

Für das kleine Spaßauto, ein Opel Astra Cabrio, ist die Situation nicht ganz so schrecklich, aber trotzdem gibt es berichtenswerte Details zur Reparatur.

Eigentlich sollte nur kontrolliert werden, warum der Rückwärtsgang sich so schlecht einlegen lässt und manchmal wieder herausspringt. Ich hatte schon die Befürchtung, dass es nicht ganz billig sein könnte - mir war klar, dass dazu das Getriebe ausgebaut werden muss.

Aber ich hatte nicht damit gerechnet, wie umfangreich die Vorarbeiten sein müssen, damit das Getriebe sich vom Auto trennen lässt: der Motor musste hochgestellt werden, dann die Kupplung und die Vorderachsen ausgebaut, und dann konnte das Getriebe vom Motor getrennt werden. Das arme Auto!

Bei der Begutachtung des Getriebes stellte sich heraus, dass der Synchronring für den Rückwärtsgang gebrochen war, vermutlich aufgrund übermäßiger Beanspruchung durch einen abgenutzten Puffer (ein billiges Plastikteil) am Ausrückhebel. Das wären die zwei halbkreisförmigen Teile unten links im Bild am Rand. Eigentlich sollte das ein ganzer Ring sein. Der Hebel hat eine Art Greifzange und ist im Bild oben Mitte (das längliche Teil).

Für andere Getriebe von Opel gibt es Reparatursätze, mit denen man alle Verschleißteile auf einmal wechseln kann (weiter oben hab ich ja erwähnt, wie aufwändig der Ausbau des Getriebes ist). Wenn man das Getriebe nämlich schon mal offen hat, soll sich der Aufwand ja lohnen, und dann macht man alles, was nötig und sinnvoll ist.

Leider ist für diese Kombination von Motor und Getriebe (für Kenner: Motor Z20LET und Getriebe F23) die Ersatzteilbeschaffung nicht kompliziert, aber umfangreich: man muss für jeden Gang die Verschleißteile einzeln ordern, und jedes Ersatzteil kostet einige Hundert Euro. So schmerzlich es ist: eine komplette Überholung mit allen Verschleißteilen hätte mich über 2000 € gekostet, und das wollte ich dann doch nicht auf einen Schlag in das Auto stecken. Also wurde nur der Rückwärtsgang repariert.

Und wo wir gerade beim "das Zerlegen muss sich doch lohnen" sind: die Verschleißteile in der Kupplung wurden auch gewechselt. Rein zufällig war sie ja auch ausgebaut. Seufz.

Bei der ersten Probefahrt mit dem neuen Getriebe hat der Werkstattinhaber dann merkwürdige Geräusche festgestellt. Das ist üblicherweise immer ein schlechtes Zeichen ... zuerst war die Vermutung, dass irgendwo ein kleines Loch in der Abgasanlage ist. Prinzipiell war die Überlegung auch richtig - leider war es der Anfang der Abgasanlage direkt am Motor. Profis nennen das defekte Teil "Krümmer", also die Verbindung zwischen Motor und Abgasleitung.

Schmerzlicherweise ist das nicht nur ein Blechteil, das die Abgase der vier Zylinder bündelt und in Richtung Katalysator schickt wie in meinem vorherigen Astra G Dreitürer - nein, in den Krümmer ist auch der Turbolader integriert. Das klingt dann schon wieder richtig teuer - ist es leider auch.

Im Krümmer war also ein kleiner Riss. Das Gefährliche daran: dort verläuft auch das Lager für die Achse des Turboladers, und wenn diese Achse plötzlich ohne Öl läuft, könnte es gefährlich werden. Ich hatte mich in den letzten Monaten schon gewundert, dass das Auto anfing, mehr Öl zu verbrauchen, aber ich schob es bequemerweise auf den ältlichen Motor mit 150.000 km. Jetzt denke ich, dass sich auf diese Weise der Riss im Krümmer langsam andeutete und entwickelte.

Nun denn, das ist aber noch lange nicht das Ende der Geschichte. Während sich also im Lauf der Woche das Drama um den Krümmer entwickelte, fiel der Fiat schon wieder aus: Schwiegermutter kam nach Hause und stellte das Auto ab. Als ich die Kinder abholen wollte, ließ sich der Fahrersitz nicht mehr verstellen. Der Beifahrersitz hat ebenfalls elektrische Sitzverstellung und funktionierte noch, ebenso die Spiegel und deren Memory-Funktion. Fazit: irgendein Bauteil oder die Verkabelung im Fahrersitz.

Also mussten wir mal wieder fliegend die Autos tauschen: der Astra wurde abgeholt und der Fiat musste gleich wieder dableiben. In der Zwischenzeit habe ich die Diagnose: der Stecker, der die Kabel vom Sitz bündelt und ins Steuergerät für die Sitzelektrik leitet, ist defekt und muss ausgetauscht werden. Kleine Ursache, große Wirkung: der defekte Sitz ist leider in der Einstellung für die Körpergröße meiner Schwiegermutter stehen geblieben. Das heißt, dass ich mit Mühe sitzen kann, aber mehr als 10 Minuten fahren kann ich damit nicht, und meine Frau ist ebenfalls kaum in der Lage, einzusteigen und zu fahren.

Bei der nächsten Fahrt mit dem Astra der Schock: es ruckelt ungemein. Ich hatte natürlich die Befürchtung, dass der neue Turbolader gleich wieder ein Problem hat, aber zum Glück ließ sich das Ruckeln durch Tauschen der Zündkerzen beheben.

Ich fürchte, langsam berechnet mir meine Werkstatt Garagenmiete ;-)

06.09.2016

Wegfahrsperre und Wegwerfgesellschaft - und das Happy-End

Zur Abwechslung will ich mir mal ein paar Gedanken (aus Berstadt ...) über ein Thema machen, das seit ein paar Jahren immer mal wieder diskutiert wird, das man aber trotzdem nicht so richtig greifen kann: die sogenannte geplante Obsoleszenz, d.h. vom Hersteller absichtlich mit dem Ziel des Ausfalls nach einer absehbaren Zeit konstruierte Geräte.

Behauptet wird diese Verschwörungstheorie immer mal wieder, insbesondere bei elektronischen Geräten. Die c't und andere Quellen berichtet auch immer mal wieder von defekten Mainboards in PCs oder von Netzteilen, in denen eine bestimmte Art von Bauteil kaputt geht: nämlich die "Elektrolytkondensatoren". Diese Bauteile altern und platzen dann gern mal auf, verlieren dabei ihren chemischen Inhalt (das Elektrolyt) und stellen deshalb ihre Funktion ein.

Ich war bislang immer skeptisch - natürlich wird diese Art von Versagen in Kauf genommen. Bauteile altern und gehen immer mal kaputt. Manche Hersteller sind vielleicht etwas - sagen wir - großzügiger bei der Auswahl der Bauteile und nehmen zugunsten des Preises eine kürzere Haltbarkeit in Kauf. Es muss ja nur halten, bis die Garantiezeit bzw. die gesetzliche Gewährleistung abläuft. Was darüber hinaus geht, ist Bonus zugunsten des Kunden und trägt "nur noch" zum guten Image bei. Aber ebenso halt insbesondere nicht zur Umsatzverbesserung. Ich kann aber nicht wirklich glauben, dass ein Einkäufer den Hintergedanken der Lebensdauer verfolgt. Das wird ein Nebenaspekt sein, der "in Kauf" genommen wird, aber mehr auch nicht.

Bislang nahm ich an, dass die Autoindustrie langlebige Ware herstellt und auch dafür sorgt, dass ihre Produkte reparierbar sind, indem für einen bestimmten Zeitraum Ersatzteile vorrätig gehalten werden.

Diese Annahme hat in den letzten Wochen einen schweren Dämpfer erlitten, und das gleich zweimal: beide unserer Autos, sowohl die Familienkutsche von Fiat als auch das kleine Spaßauto von Opel hatten Defekte, für die es vom Hersteller keine vernünftige Ersatzteillieferung mehr gibt.

Aber der Reihe nach. Die Geschichte hinter unserem defekten Fiat Ulysse (Bj. 2003) ist eine mit einem mehr als sechswöchigen Werkstattaufenthalt mit Höhen und Tiefen, die man in ihrer Gesamtheit kaum glauben kann.

Irgendwann neulich passierte das hier: meine Frau (natürlich die beste Ehefrau von allen ...) hat das Auto in den Hof rangiert, und das Zuschließen mit der Fernbedienung im Schlüssel klappte plötzlich nicht - Fenster schlossen nicht und Türschloss verriegelte auch nicht. Na gut, könnte auch die Batterie in der Fernbedienung sein. Also Schlüssel ins Schloss stecken - aber es passierte trotzdem nichts. Auch der Motor sprang nicht mehr an; der Anlasser orgelte, aber der Motor weigerte sich. Die örtliche Werkstatt kam mit der ambulanten Ausstattung, fand eine defekte Sicherung für die Innenbeleuchtung, aber nicht die grundsätzliche Ursache, also wurde der Wagen in die Werkstatt geschleppt.

Da unser Fiat schon mal elektrische Probleme hatte (Kabelbruch), wurden zunächst alle Kabel getestet. Dies wurde erschwert durch die Tatsache, dass es nicht einen einzelnen Schaltplan gibt, sondern mehrere, die eine Werkstatt einzeln kaufen muss. Diese ganzen Untersuchungen dauerten schon mal mehr als zwei Wochen, und das ist ganz schön bitter, wenn das große, praktische Auto so lange nicht zur Verfügung steht.

Langer Rede, kurzer Sinn: das Ergebnis war, dass das zentrale Steuergerät defekt war, das im Sicherungskasten untergebracht ist. Dieses Steuergerät ist neu nicht mehr bei Fiat lieferbar - es hätte um die 800 € gekostet, falls doch.

Aber ich hatte Glück im Unglück: bei Ebay fand ich einen Autoverwerter kurz hinter Frankfurt, der aus einem fast baugleichen Lancia mit Benzin-V6-Motor einen solchen Sicherungskasten anbot - und das für sagenhafte 30 €! Rein zufällig war meine Frau sogar an dem Tag gerade in Frankfurt unterwegs und sie konnte das Ersatzteil eine Stunde nach dem Kauf schon abholen und bei der Werkstatt in Berstadt abgeben.

Nach dem Ein- und sonstigen Zusammenbau und der Umprogrammierung auf den Motortyp Diesel in unserem Fiat kam dann die Ernüchterung: alles funktionierte wieder (Scheiben, Schlösser, Licht etc.) - außer dem Motor. Er wollte nicht anspringen, und das führte dann schließlich zu der Erkenntnis, dass in diesem Steuergerät die Wegfahrsperre drinstecken muss.

Das war erschreckend, aber nachdem nun die ganze Geschichte ausgestanden ist (es geht gleich weiter), schließt sich an dieser Stelle zunächst der Bogen zu meiner einleitenden Bemerkung über die geplante Obsoleszenz: in diesem Steuergerät ist die Wegfahrsperre verbaut, und nur der Hersteller ist in der Lage, mit dem Nachweis des Fahrzeugbriefs und der Fahrgestellnummer das Steuergerät so zu programmieren, dass es zum zu reparierenden Auto passt. Da sich Fiat durch Nichtlieferung des Steuergeräts also offensichtlich weigert, dieses Modell Fiat Ulysse weiter fahren zu lassen, ist dies meiner Meinung nach tatsächlich ein Fall von gewolltem und geplantem Ausfall.

Wenn man es vom kryptografischen Standpunkt betrachtet, ist die Wegfahrsperre ungefähr vergleichbar mit Verschlüsselung von WLAN: es gibt eine Instanz, die den Zugang kontrolliert (hier WLAN, dort Motor), und nur wenn man den Besitz oder das Wissen um ein Geheimnis nachweisen kann (hier WLAN-Passwort, dort Schlüssel mit Chip), bekommt man den Zugang gewährt.

Dies ist ein Herstellermonopol: allein Fiat weiß, wie die Technik funktioniert, um die Wegfahrsperre zu programmieren. Besonders schmerzhaft also, wenn die Produktion des Ersatzteils eingestellt wird und es auch keine sonstige Möglichkeit von Fremdherstellern gibt, die in die Bresche springen könnten. Auf der einen Seite ist dies natürlich gewollt: wenn jemand außer Fiat es könnte, wäre es kein Problem, einen Fiat zu stehlen und ein neues Steuergerät zu programmieren. Auf der anderen Seite steht der gelackmeierte Kunde, wenn der Hersteller sich weigert, ein Ersatzteil für eine Reparatur zu liefern.

Zu unserem riesigen Glück gibt es Firmen, die auf die Reparatur von elektronischen Autokomponenten spezialisiert sind, und eine solche konnte tatsächlich nach gutem Zureden aus dem alten und dem neuen Sicherungskasten kombiniert ein funktionsfähiges Gerät zusammenbauen. Kompliziert war nur, dass die Wegfahrsperre auch mit dem eigentlichen Motorsteuergerät in Verbindung steht, also musste dieses Steuergerät auch noch ausgebaut werden, und die Spezialwerkstatt benötigte auch noch einen unserer Autoschlüssel.

Nach etwa einer Woche wurde das reparierte Teil zurückgeschickt, und nach dem Zusammenbau fiel uns allen ein Stein vom Herzen: die Familienkutsche fährt wieder.

Einziger kleiner Schmerz: statt der tatsächlich gefahrenen 145.000 km hat der Tacho nun 300.000 km in der Anzeige. Der Kilometerstand wird also irgendwo in einem der Chips gespeichert, die aus dem Spender-Lancia in unseren Fiat gewandert sind. Da wir aber die vollständige Werkstattdokumentation haben, ist dies vernachlässigbar. Hauptsache, es fährt wieder!

Und morgen, liebe Kinder, erzähle ich den Rest der Geschichte mit dem Rückwärtsgang im Zweitwagen Opel Astra.

03.09.2016

Hintertüren in Software - Leserbrief

Im Moment macht der Innenminister mal wieder heiße Luft im Blätterwald mit der Forderung, staatliche Hintertüren in Software einzubauen, z.B. in Smartphones. Die Idee finde ich so blöd, dass ich einen Leserbrief dazu schrieb.
Bezeichnend für die politische Grundhaltung der WZ ist die Kürzung (so markiert).
[Veröffentlicht am 03.09.2016]

Unser Innenminister de Maizière fordert also mal wieder, dass Softwarehersteller Hintertüren in ihre Produkte einbauen sollen.

Diese Hintertüren gibt es schon lang: man nannte sie bislang Sicherheitslücken, die durch schlechte Programmierer entstanden sind.
Für Sicherheitslücken gibt es seit Jahren einen Markt, auf dem sich private Bösewichte genauso tummeln wie Staaten.
Nur mal so als Stichwort eine der erschreckenden Tatsachen dieses Marktes: Lücken, die einem Schädling das dauerhafte Einnisten in ein Gerät ermöglichen, d.h. auch einen Neustart des Geräts überstehen, werden mit Summen ab 100.000 Dollar gehandelt.

Aus der aktuellen Debatte über die "Pegasus"-Sicherheitslücke in iPhones (technisch eine schlaue Kombination von vier Lücken), auf die Apple vorbildlich in nur 10 Tagen reagiert hat und nun iOS 9.3.5 verteilt, lernen wir Folgendes:
Sicherheitslücken sind eine ganz schlimme Sache, die so schnell wie möglich behoben werden müssen, weil (natürlich) nicht nur die "Guten" sie ausnutzen, sondern ganz schnell auch die Bösen. Hier bricht ironischerweise die Klassifizierung zusammen: die "Bösen" sind in diesem Fall vermutlich ein Staat, dem der angegriffene Aktivist ein Dorn im Auge war, und die halten sich selbst natürlich wiederum für die "Guten". Alles ist relativ.

Wenn nun sogar noch bekannte Sicherheitslücken in die Geräte eingepflanzt werden (eben die von de Maizière geforderten Hintertüren), dann werden schlagartig alle unsere elektronischen Geräte gefährlich. Man muss nämlich nicht mehr aktiv nach Sicherheitslücken forschen und herausfinden, wie man durch die Kombinationen mehrerer Lücken sein Ziel erreicht, sondern es reicht, den einen Mitarbeiter eines Geheimdienstes oder des Softwareherstellers zu bestechen oder zu bedrohen, damit er die Details der Hintertür weitergibt. Es gibt keine Hintertür, die nur für die "Guten" existiert.

Wer würde denn so eine Hintertür einbauen? Der Hersteller natürlich. Und so, wie ich große Firmen kenne, wird so eine Hintertür dann in etwa 300 Software-Entwicklern bekannt sein. Die sitzen in einem Land, das nicht der deutschen Rechtsprechung unterworfen ist. Man kann sich ausrechnen, wie "sicher" so ein Produkt sein kann.

Besonders schlimm: Geheimdienste wie der amerikanische NSA sitzen mitunter jahrelang auf dem Wissen über Sicherheitslücken (sogenannte "zero day exploits", also Lücken, die ausgenutzt werden, aber dem Hersteller nicht bekannt sind), weil sie sich einbilden, die einzigen mit dieser Kenntnis zu sein. Aber natürlich ist es nicht so: wenn ein Geheimdienst eine Lücke finden oder kaufen kann, ist dies jedem anderen Bösewicht ebenso möglich. Das Zurückhalten solcher Kenntnisse gefährdet also uns alle, bei fraglichem Nutzen über eine zukünftige Gelegenheit, die vielleicht sogar nie kommen wird.

Genau das ist das Perfide an dieser Pseudo-Diskussion: Politiker fordern etwas, von dem sie nichts verstehen, und wovon jeder Sicherheitsforscher abrät. Aber die Forderung selbst, untermauert von populistischen Begründungen wie Terrorbekämpfung, steht im Raum und wird wieder und wieder diskutiert, bis der Widerstand erlahmt. Aber der mögliche Nutzen steht in keinem Verhältnis zum definitiven Schaden für alle, wenn so ein Quatsch in ein Gesetz gegossen wird.

Die Sicherheit vor elektronischen Schädlingen wäre höher, wenn sich der Bundesinnenverteidiger de Maizière um ein Gesetz zur Update-Pflicht für Sicherheitslücken kümmern würde, statt hohle Phrasen über den "rechtsfreien Raum" zu dreschen.

Wie schnell kommt denn das Update für ein Gerät in Deutschland, das nicht gerade zur Spitzenklasse gehört? Eben. Die einzigen Smartphones mit einigermaßen zuverlässiger Update-Garantie sind von Microsoft (Windows Phone), Apple (iPhone) und Google selbst (Nexus). Alle anderen Hersteller liefern Updates nur für das Top-Gerät des Jahres aus, mit Glück noch für das vom Vorjahr. Und das war's dann auch schon. Das Billig-Smartphone bezahlen wir also mit fehlender Sicherheit, weil nach Auslieferung die Uhr tickt und man sicher sein kann, dass die Software Fehler und damit Lücken enthält.