Posts for the month of May 2008

FoneLink 2.0

Yay!

Nachdem wir das Innenleben der Software fast komplett ausgetauscht haben ist  endlich die Version 2.0 fertig geworden.

Was ein Akt.

Von dem was die Software ausmacht, ist wirklich kein Stein mehr so gelassen worden wie er war.

Jede operation wurde Asyncron gemacht, alles in ein Konzept von Aktionen gepresst (und das war manchmal nicht einfach) die gescheduled werden und (wenn es das Telefon erlaubt) sogar parallel ausgeführt werden können.

Mein Hauptteil daran war das Datenmodell das den synchronen Zugriff auf das Dateisystem des Handies erlaubt - intern aber alle Operationen Asynchron abarbeitet.

Was gar nicht so einfach zu verkapseln war. (Dementsprechend sind die Unit Tests auch fast die noch mal halb so viel Code wie der eigentliche Code).

Das Design für das ich mich letztendlich entschieden habe ist recht simpel: Jeder Dateisystem-Knoten kann einen von mehreren Zuständen haben:

  1. Out Of Date -> Der Zustand muss mit dem Handy abgeglichen werden
  2. "Up To Date" -> nichts zu tun, die aktuellen Daten sind da
  3. Update In Progress-> Die Daten werden gerade Aktualisiert oder ein anderer Job (Meist mit Progress-Anzeige) läuft mit Bezug auf diesen Knoten.

Jobs können zum Beispiel das Kopieren auf oder von dem Handy sein.

Dazu kommt dann natürlich noch etwas Intelligenz die diese Jobs automatisch anwirft wenn es Sinn macht (Verzeichnisse Aktualisieren wenn die GUI sie anzeigt) und unnötiges Kopieren vermeidet (Es gibt einen Cache auf der Festplatte - wird eine Datei einmal vom Handy Kopiert und dann nicht mehr Verändert wird die Kopierte ab da für Operationen verwendet.) Und nicht zu vergessen: Versionierte Backup und Restores gibt es natürlich auch noch.

Ach ja und Rasend Schnell sollte das natürlich auch sein.

War nicht leicht - aber jetzt läuft es rock-solid. Und über die Implementierung erzähle ich später mal mehr.

Spaces in the path

are not allowed on UNIX.

Damn.

Um das klarer zu machen: Ich will ein Skript schreiben, bei dem oben im  shebang hartcodiert ein Pfad zum interpreter steht.

So weit so gut. ABER. Dieser Interpreter liegt in einem Verzeichnis - und dieses Verzeichnis hat ein Leerzeichen im Namen.

Doh.

Die Regeln sagen nämlich:

The initial line of a script file must begin with #! as the
first two bytes, followed by zero or more spaces, followed by
interpreter or interpreter argument.  One or more spaces or tabs
must separate interpreter and argument.  The first line should
end with either a new-line or null character.

Und da hält sich auch der Mac OS X Kernel genau daran.

 Ich bin auch nicht der erste der darüber gestolpert ist. Hallo Felix. :-)

Das Blöde daran: Die Implementierungen erlauben weder ein Escapen, noch ein "In Anführungszeichen Setzen" des Interpreters.

Hrmpf.

Nach einigem Nachdenken sind mir letztlich nur zwei Lösungsmöglichkeiten aufgefallen:

1) Das Programm in zwei Dateien aufsplitten - die erste startet mit /bin/sh im shebang und dann ganz normal im 'body' den normalen Interpreter mit den normalen Mitteln der Shell (die auch quotes und escapen erlauben).

2) Wenn das Programm ein File bleiben soll / muss, kann ein  Polyglot das Problem lösen.

Das sah bei mir dann so aus:

#!/bin/sh
# Solves the problem that shebang lines can't contain spaces 
# (even escaped or quoted) in the interpreter path via a polyglot
"""false"
exec /Users/dwt/Archiv/Code/Aktive\ Projekte/Trac/env-trac-0.11/bin/python $0 $@
"""

import sys
print sys.argv

Das funktioniert so:

  • wird die Datei gestartet, wird sie mit der Bourne Shell (oder einer der Nachkommen) ausgeführt
  • in der Zeile """false" maskiere ich mit Hilfe des Kommandos "false" den Beginn eines Python Doc-Strings / Kommentars / Multiline-Strings.
  • Danach wird mit "exec" die Datei nochmal ausgeführt - diesmal mit dem richtigen Interpreter.
  • Der überspringt diesen Teil dann weil für ihn der Start komplett im Kommentar / ... / ... verschwindet.

Einerseits finde ich es cool das ich diesen Workaround gefunden habe - andererseits ist das natürlich ein totaler Hack. Insofern bin ich eher dagegen.

Was ich jetzt damit Tue weiß ich jedenfalls noch nicht.

Liquid Democracy

Heute hat mich Bernd auf diesen coolen Wikipedia-Artikel hingewiesen:  Proxy Voting. Dort wird das was wir uns bei der Piratenpartei Berlin als Liquid Democracy vorstellen sehr schön beschrieben - insbesondere auch mit vielen Beispielen wo das schon angewendet wird.

Spannend finde ich auch das ein paar Leute wohl gleich versucht haben das in der Wikipedia einzuführen - erst mal ohne Erfolg.

 Aber die Diskussion darum ist sehr lesenswert.

Debugging Unit Tests in Xcode 3.1

Since I haven't found this info anywhere in the Blogosphere and had to painfully gather it through a long debugging stare, I'm posting it here:

If you want do debug Unit Tests in Xcode 3.1 you have to do the usual, that is:

  • Make a custom Executable
  • Set it's argumet to -SenTest All
  • Set some Environment Variables
    • DYLD_INSERT_LIBRARIES to ${DEVELOPER_LIBRARY_DIR}/PrivateFrameworks/DevToolsBundleInjection.framework/DevToolsBundleInjection
    • DYLD_FALLBACK_FRAMEWORK_PATH to $(DEVELOPER_LIBRARY_DIR)/Frameworks
    • XCInjectBundle to $(BUILT_PRODUCTS_DIR)/InvocationBuilder Tests.octest This is of course where you have enter the name of your test bundle

So far nothing new.

What is new though is that you also set the variable XCInjectBundleInto to point to the executable that is going to load the tests (probably to avoid the 3.0 Bug that would load the tests into the shell that GDB used to start the Application). This should be the same as the $(TEST_HOST) variable that you have to set for the Unit Test bundle. In my case this is $(BUILT_PRODUCTS_DIR)/InvocationBuilder.app/Contents/MacOS/InvocationBuilder.

This is quite interesting, since it means that otest is not used anymore to start the tests, but instead RunTargetUnitTests executes the tests directly.

Well, now that I can again debug my tests maybe I'l even get it to work with debugging Unit Tests which use Mock-Objects sometime. :-)

  • Posted: 2008-05-25 09:45 (Updated: 2008-05-25 09:46)
  • Author: dwt
  • Categories: code
  • Comments (0)

Über Fehlermeldungen aus alten Tagen

.. bin ich mal wieder in  Wards Wiki gestolpert.

Lovely. :-)

Wie man über Objektorientierung nachdenken kann

Eines meiner Lieblingszitate über Objektorientierung kommt von  Ward Cunningham: "Jedes Objekt ist eine kleine Sprache".

Ich verstehe das so das man mit jedem Objekt das man entwirft eine kleine Sprache schreibt. Eine Sprache die es einfach macht die lösung für ein spezifisches Problem darzustellen.

Fast noch wichtiger finde ich aber jetzt gerade (wo ich mich  auf Arbeit mit vielen globalen Variablen herumschlage) das jedes Objekt eben auch einen eigenen Namensraum darstellt - der optimaler weise auch verschachtelt werden kann.

Wunderschön finde ich das zum Beispiel bei Ruby sichtbar: Wenn man in eine Datei direkt Code schreibt, dann ist dieser Code teil eines top-level objekts. Schreibt mann in einer Datei dann weitere Objekte, sind diese Objekte in diesem top-level objekt eingebettet.

Das Prinzip erweitert sich wunderbar zu paketen und paketen von paketen - öffentlichen und privaten klassen (fals man das braucht) etc.

Und das alles ohne ein weiteres Konzept einzuführen - nur die Objektabstraktion. (*schnief* Java?)

Warum nur machen das so wenige Programmiersprachen so? Objective-C jedenfalls hat noch nix in die Richtung. In C++ hat man sowieso verloren - C hat gar keine Objekte - aber man kann dafür jede Bibliothek als Objekt sehen (so man will).

Stellt sich die Frage: Übersehe ich irgend ein total geiles Feature das man erhält wenn man Pakete als ein eigenes Feature in eine Sprache einbaut?

Hmpf.

Genshi

Heute habe ich mir mit  Felix den Template Teil des Blogs, an dem wir gerade schrauben, angeschaut. Ziel war es eine Blog-Posting Seite zu bauen die möglichst einfach zu warten ist und gleichzeitig möglichst alle Features bietet die auch die  Standard Wiki-Editier-Seite von  Trac bietet.

Das geht überraschenderweise sogar ganz gut. Denn: Trac ab 0.11 verwendet Genshi als Template-Sprache und Genshi wiederum ist XML mit  XPath allüren.

Will heißen wir konnten uns das Template für die normale Wiki-Eingabe nehmen und dann sagen: Aber die Überschrift oben "Editing XXXXX" soll bitte weg und dafür soll da stehen "Create Blog Entry" - ein Feature das die meisten Template-Engines schon mal nicht bieten.

Und das ist natürlich geil, weil wir nicht den kompletten Template-Source kopieren müssen um das gleiche look und feel zu kriegen.

Nur das XPath natürlich wie alles bei XML total kompliziert macht. Das heißt zum Beispiel das man damit nicht sagen kann, nimm dass und ersetze darin das gegen dies. Neeeiiiin. Natürlich ist alles andersherum.

Man sagt also: Meine Welt ist so definiert, das dies immer wenn es auftritt durch das ersetzt wird und jetzt hole ich mal das original in meine Welt hinein und magisch wird darin alles ersetzt.

Großartig.

Klar das geht - aber das hätte man auch einfacher haben können.

p.s.: Weiß jemand wie man mit XPath aus dieser Struktur

<fieldset id="changeinfo">
 <legend>Change information</legend>
 
 <div class="field">
    <label for="tags">Tag under: (<a href="http://xn--hcker-gra.net/cgi-bin/trac.cgi/tags">
                            view all tags</a>)</label><BR/>
    <input title="Comma separated list of tags" type="text" id='tags' 
                name="tags" size="30" value="blog">
 </div>
 <div class="field">
  <label>Comment about this change (optional):<br />
  <input id="comment" type="text" name="comment" size="60" value="" /></label>
 </div><br />
 
  <div class="options">
   <label><input type="checkbox" name="readonly" id="readonly" />
   Page is read-only</label>
  </div>
 
</fieldset>

nur das div mit dem label und input für den Kommentar herausmatchen kann?

Unsere Versuche sind erst einmal bei diesem XPath query stehen geblieben div[@id='changeinfo1']/div[@class='field'].

Oh und noch was zum Tanzen

  • Posted: 2008-05-19 21:17
  • Author: dwt
  • Categories: (none)
  • Comments (0)

Parteitagsfazit

Boah war ich gestresst von der Versammlung - aber zumindest ist das Ergebnis zufrieden stellend - die wichtigsten Änderungen zur Satzung sind durchgekommen:  Die neue Finanzordnung und  die Regelung zum dezentralen Parteitag.

Sonst war aber leider nicht viel los - die Tatsache das so viele Piraten auf einem Fleck saßen konnte nicht genutzt werden - ausser um über GO-Anträge zu streiten.

Der Inhaltlich produktivste Teil der Veranstaltung wohl das gemeinschaftliche Besäufnis am Abend nach dem ersten Tag. Da wurde wenigstens mal überhaupt etwas Inhaltliches getan (Wenn ich mich auch nicht mehr an alles erinnern kann).

Also ein gemischtes Fazit.

Regeln

haben immer einen Grund aus dem heraus sie entwickelt wurden. Nur leider wird dieser Grund viel zu oft beim Vermitteln der Regeln nicht mehr mitgereicht.

So gibt es Programmierer die ihren Code nicht einrücken weil sie den Grund dafür nicht kennen oder verstehen und Politiker die z.B. am Patentsystem schrauben ohne zu verstehen was der Grund dafür eigentlich war.

Und genau das ist ein Problem - jede Regel hat einen Sinn - und diesen Sinn kann man nur bewerten wenn man eben genau weiß warum sie eingeführt wurde.

Denn wenn dieser Sinn nicht mehr erfüllt wird, dann muss man die Regel verändern.

Und das fällt schwer - vor allem wenn es eine Gruppe von Menschen ist (sagen wir 40-100) die sich jetzt gerade an ein paar Regeln gewöhnt hat und noch nicht weiß wie ihre Zusammenarbeit unter den neuen Regeln aussehen wird.

Piratenpartei treibt Dollarkurs in die Höhe

"Nur haarscharf ist das amerikanische Volk heute der Dollarkatastrophe vorbeigeschrammt" so Winfried Engelke.

Engelke hatte in einem Akt heroischer Selbstaufopferung bei der Versteigerung des letzten und einzigen Dollars in der Piraten Barkasse (nein, nicht  diese) den Preis auf die Spitze getrieben und ihn für astronomische 20 € erworben.

"Dies ist der Beginn einer neuen Ära" mit diesen Worten leitete Engelke die Tradition des immer wieder versteigerns dieses Dollars zu jedem Parteitag ein.

Wir sind begeistert.

Die Piratenpartei ist groß

denn sie hat 804 Mitglieder.

Also im letzten Jahr etwas mehr als ein Mitglied pro Tag.

Parteitagswahnsinn

 GO Antrag auf:

  • Ende der Diskussion und Beschlussfassung -> Angenommen
  • Großer Protest des noch-Vorsitzenden
  • Daraufhin sein GO Antrag keine weiteren GO-Anträge auf Ende der Diskussion und Beschlussfassung zu stellen -> der wurde Angenommen
  • Daraufhin der Verweigerung des Versammlungsleiters die restlichen Diskutanten noch reden zu lassen, weil der Antrag auf Ende der Diskussion vor dem GO Antrag der das verhindern möchte beschlossen wurde
  • Daraufhin der GO Antrag die Diskussion wieder zu eröffnen
  • Und dann ging die Diskussion weiter
  • Viele viele GO Anträge später...
  • Und dann gab es GO Anträge die Sitzung auf morgen zu Vertagen

ARGHHHHHHH

Interessante Begriffe:  Filibuster

Was ist die Piratenpartei

Von dem Mitgliederausweis hinten:

Der Besitzer dieses Dokumentes ist berechtigt, sich seines Verstandes zu bedienen, Informationen zu produzieren, replizieren und konsumieren, sich frei und ohne Kontrolle zu entfalten in Privatspähre[sic] und Öffentlichkeit.

Behinderung dieser Rechte wird geahndet durch die Piratenpartei Deutschland.

Großartig!

  • Posted: 2008-05-17 17:09 (Updated: 2008-05-17 17:09)
  • Author: dwt
  • Categories: politik
  • Comments (0)

Parteitagsstimmung

Mal ein paar Stichworte:

  • Schöne gerade Tischreihen, streng Schulisch aufgestellt
  • Der Versammlungsleiter und die Vorsitzenden sitzen auf der Bühne vorne
  • Es gibt kaum Internet, nach langem hakeln haben wir wenigstens eine UMTS-Flat per W-Lan freigegeben
  • Endlose Diskussionen, Satzungsänderungsanträge, Satzungsänderungsänderungsanfragen ("selbstverständlich" ausgeschlossen)
  • Harte Sitze
  • Kaffee kostet extra
  • Es sind immer noch weit über die hälfte der 90 Satzungsänderungsanträge offen

*schnief*

Der Traum vom Fliegen ...

... ist schnell ausgeträumt wenn man sich  die Liste der Änderungsanträge für den Piratenparteitag anschaut.

Da kann man wirklich nur noch von einer  DOS Attacke sprechen.

Ich bin mal gespannt was wir daraus machen werden - ob sich wohl dieses Jahr mehr Leute vorbereitet und alles mal gelesen und sich eine Meinung gebildet haben?

Ich hoffe ja für das nächste Jahr, das man im Wiki jedem Antrag Punkte geben kann, damit wenigstens die wichtigsten nach vorne kommen.

Für dieses Jahr wünsche ich mir, dass alle, die noch Diskussionsbedarf haben, in einem Raum eingeschlossen werden und dort Diskutieren bis sie genug haben, während der Rest sich um andere Dinge kümmern kann. Die Abstimmungen werden dann gerafft in einem Zeitraum ohne viel Diskussion gemacht damit es schnell geht.

Na mal schaun.

Update: Tja, die Merhheit hat sich nicht vorbereitet und möchte das sich der Rest auch mit ihnen in Diskussionen abbricht. Mal schauen wie viel Zeit dann noch übrig bleibt.

Experimentalphysik und Programmieren

Das sind an sich identische Tätigkeiten - hat mir mein Vater heute klargemacht.

Klar, er ist ein alter Physiker und trauert immer noch ein wenig der Tatsache nach das ich keiner geworden bin.

Oder auch nicht, denn: Ein guter Experimentalphysiker arbeitet so, dass er in einer Versuchsreihe in jedem Schritt immer nur eine Variable verändert um methodisch vorzugehen. Entweder nimmt er eine (wirklich nur eine) Änderung an seinen Messinstrumenten, oder an dem Experiment vor.

Dazu dann natürlich noch einiges an Intuition welche Veränderung sinnvoll ist - experimentelle Physik ist eben auch eine Kunst, genau wie das Programmieren.

Ach ja, und natürlich schreibt er ein Protokoll um hinterher nachvollziehen zu können, was er eigentlich getan hat.

Beim Programmieren kann man diese Techniken genau so wiederfinden. Die Messinstrumente sind in der Regel  UnitTests oder etwas äquivalentes (wobei UnitTests besser geeignet sind, da sie exakter messen können) und damit wird eine API dann abgeklopft.

Jetzt kommt bei uns Programmierern aber noch eine komplette Dimension dazu. Denn während ein Experimentalphysiker die Welt um ihn herum so hinnehmen muss wie sie ist, können wir Programmierer den Gegenstand unserer Tests beliebig verändern. Nur unser Phantasie schränkt uns ein.

Aber es läuft genauso: Ein Messinstrument, ein Stück Weltveränderung, ad infinitum.

Das letzte fehlende Detail ist das Logbuch: Das sind die schon geschriebenen Tests, die dokumentieren was wir schon herausgefunden haben.

Ich war wirklich überrascht wie weit die analogie trägt. Und auch die Implikation gefällt mir als UnitTest-Fan natürlich sehr. Und natürlich auch der Fakt das wir als Informatiker 'wieder mal' mehr können als die Physiker.

:-)

Wann darf man eigentlich…

…die Syntax einer Sprache modifizieren?

In C natürlich. Das Problem ist klar: Makros können ja beliebige Ersetzungen im Text vornehmen und dann mit vielen Makros aus C Pascal zu machen geht auch - aber das will man ja nicht, denn sonst hat man das gleiche Problem wie die  Bourne- Shell die irgendwann niemand mehr weiterentwickeln konnte.

Klar.

Andererseits nervt es wirklich unter Cocoa z.B. für jede Iteration über einen Array das hier zu schreiben:

NSArray *someStrings = [NSArray arrayWithObjects:@"first", @"second", @"third", @"fourth", nil];

NSString *eachString = nil;
NSEnumerator *enumerator = [someStrings objectEnumerator];

while (eachString = [enumerator nextObject])
{
    NSLog(@"eachString is %@", eachString);
}

Das heißt, für eine Schleife (zwei Zeilen) ha man noch mal mindestens zwei weitere Zeilen nur für das Setup.

Das nervt so sehr, das viele Leute das etwas kürzen:

NSArray *someStrings = [NSArray arrayWithObjects:@"first", @"second", @"third", @"fourth", nil];

id eachString, enumerator = [someStrings objectEnumerator];
while (eachString = [enumerator nextObject])
{
    NSLog(@"eachString is %@", eachString);
}

Schon besser, aber man verliert die Typchecks (falls man die haben will) und man muss trotzdem noch eine langweilige Zeile schreiben, die immer gleich ist und sich nicht wirklich kürzen lässt.

Jetzt kann man natürlich unter C schön ein Makro bauen, was das schöner macht - aber, siehe  Bourne Shell...

Aber, mit  ObjC 2.0 gibt es das for(String *each in someStrings) konstrukt, das schon deutlich kürzer (und auch schneller - aber aus anderen Gründen) ist.

Also, doch mal ein Makro. Nach reiflichem (2 Minuten) überlegen hab ich mich entschieden es erst einmal mit einer for Schleife zu probieren, da das bedeutet das der Scope der Variablen schön beschränkt ist.

Ziel wäre es also, das hier schreiben zu können:

NSArray *someStrings = [NSArray arrayWithObjects:@"first", @"second", @"third", @"fourth", nil];

FOREACH(eachString, someStrings)
{
    NSLog(@"eachString is %@", eachString);
}

Und das sähe dann so aus:

#define FOREACH(each, collection) \
    for(id __enumerator = [collection objectEnumerator], each = [__enumerator nextObject]; \
        each; \
        each = [__enumerator nextObject])

In der Praxis hab ich es auf Wunsch meiner Kollegen noch etwas modifiziert, damit man den Typ der Variablen noch einstellen kann (auch wenn er bisher noch nicht verwendet wird - immerhin kann man ihn aber als Startpunkt für Dokumentations-Lookup verwenden).

/// Use like this:
// FOREACH(NSString *, each, arrayOfStrings)
// {
//      if ([each hasPrefix:@"foo"])
//          [self doSomething];
// }
// This macro is in preparation of the ObjC 2.0 Fast enumeration protocol
#define FOREACH(typeOfEach, each, collection) \
    for(id __enumerator = [collection objectEnumerator], each = [__enumerator nextObject]; \
        each; \
        each = [__enumerator nextObject])

Bei Verwendung, bitte e-mail. :-)

Wie man die Löschen Taste implementiert

sag ich heute nicht, aber dafür welch hervorragenden Podcasts ich gerade gehört habe:

  •  Energiesparhäuser Hochspannender Einblick was die Haustechnik so her gibt und wie ähnlich sie der Computertechnik ist.
  •  Hubschrauber Wie eine Voraussage über einen Hubschrauberabsturz (wahre Geschichte) ein Leben verändert.

Beides hoch spannend. :-)

cu Martin

Mein Name ist Martin und ich bin ein Pirat

Denn das worum es heute geht ist die Frage wer die Kultur von Morgen kontrolliert.

Die die es heute noch tun - oder die die sich gerade anschicken diese Kontrolle zu unterlaufen?

Die Wissenschaftler, die Privatmenschen, die Berufsausübenden, die Künstler - alle, die jetzt nicht mehr durch einen Engpass (auch Firma genannt) davon abgehalten werden können ihren Sermon zu veröffentlichen.

Manchmal werden diese Menschen Blogger genannt, aber es geht um etwas viel größeres.

Unsere Kultur. Was wir daraus machen. Wie wir sie machen.


Das ist in etwa die Meinung von  Rickard  Falkvinge die er in  immer wieder Vertritt.

Heute kriegt er erst mal meine Zustimmung. An die Kritik mache ich mich Später.

Den Mobile Monday

 hab ich gerade besucht.

Und ich muss sagen: "I am not impressed."

Obwohl nahezu alle anwesenden Deutsche waren, wurden "natürlich" alle Vorträge auf Englisch abgehalten. Sehr Hipp, aber leider auch in sehr brüchigem Englisch das vieles Verstehen eher erschwerte. :/

Überhaupt das Verstehen. Wenn ich es recht betrachte, dann war das eigentlich kein Problem. Denn das Niveau der Vorträge war so tief, das selbst das gebrochene Englisch vieler Vortragender nicht wirklich am Verstehen der nicht vorhandenen Inhalte störte.

Was genau ist das also für eine Veranstaltung?

Eine IT-Second-Generation-Gründer-Blase trifft sich dort und präsentiert zum Teil ihre Ideen - aber auch Vertreter von größeren Firmen kommen vorbei (in diesem Falle Vodafone) um ihre Produkte zu zeigen. (Getragen wird das ganze von  DER Post (?), Nokia,  Sun, Jamba...

Und dann sind natürlich immer auch Event Sponsoren, hier Kyte und Device Anywhere die die Gelegenheit nutzten um wenigstens ein paar Leuten ihre Software bekannt zu machen.

Insgesammt erinnert mich das Stark an einen Spruch den  Bernd ( wunderschönes Bild) vor einiger Zeit einmal getätigt hat: "In Berlin funktioniert das so: Es gibt viel mehr Aktive die etwas cooles machen wollen, als Leute die sich das ansehen wollen. Daher gibt es die soziale Übereinkunft, das man immer zu den anderen Leuten geht wenn sie was machen und die dafür auch auf die eigenen Veranstaltungen kommen wenn man selber eine macht."

Well, genau so hat es gewirkt. Und eher uninteressant. Leider.

Den das Thema  User Centered Design ist sauwichtig und völlig unterbelichtet.

Peinlich fand ich auch, das ausgerechnet der Typ der Von Jamba da war den besten Vortrag über User-Centered design abgeliefert hat den der ganze Abend zu bieten hatte. :-/

Der Grund wieso ich eigentlich hingegangen bin, nämlich der Vortrag von Jan Mühlig ( von Relevantive) ist leider ausgefallen. Wirklich schade. Ich bin sicher er hätte noch am ehesten etwas relevantes sagen können.

Warum jeder überall das gleiche Passwort verwendet …

… wo doch jeder weiß wie unsicher das ist?

Dabei ist dass Problem so klar: Niemand kann sich für jeden Account den man heute im Social Web anlegen muss eine neue Kombination aus Benutzername und Passwort merken.

Und es gibt mehrere Lösungen:

Microsoft (aber auch viele Andere) favorisiert Single-Sign-On - ein Server von Microsoft verwaltet die Benutzerdaten für alle Webseiten. Man meldet sich nur noch bei Microsoft an und alle anderen Sprechen nicht mehr mit einem selber, sondern nur noch mit Microsoft um festzustellen ob der der da rein will echt ist.

Super, nur noch ein Passwort - aber auch ein Punkt an dem alles schief gehen kann. Denn man muss dem Anbieter (Microsoft) vertrauen.

Apple hat eine Andere Lösung:  Keychain. Ganz Apple Typisch komplett in das System integriert und nicht nur eine Lösung für Webseite, sondern für jedes Authentifizierungsproblem.

Super, auch nur noch ein Passwort und keine zentrale Location der man Vertrauen muss (abgesehen von der Implementierung des Dienstes). Aber, wenn man mehrere Computer verwendet oder auch mal aus der Ferne auf eine Webseite zugreifen muss / möchte, hat man erst einmal verloren.

Und da habe ich heute die perfekte Lösung gefunden: Ein Javascript Bookmarklet das folgendes tut: Es verbindet ein konstantes Geheimnis (Master Password) mit einem Datum das für jede Webseite variiert (die URL oder den Namen der Seite) und jagt das Ergebnis durch eine  Kryptographische Hash-Funktion.

Das Ergebnis ist damit ein Passwort das für jede Webseite anders ist - aber das man sich nicht merken muss.

Das  Bookmarklet gibt es hier.  Und natürlich gibt es dafür auch eine Greasemonkey verschönerte Version für Firefox Benutzer. (Die Angenehmerweise auch auf dem iPhone funktioniert)

Ich verwende auf dem iPhone dieses Bookmarklet ( Als Backup gespeichert)

javascript:(function(){function%20hex_md5(s){%20return%20binl2hex(core_md5(str2binl(s),%20s.length%20*%208));}function%20core_md5(x,%20len){x[len%20%3E%3E%205]|=%200x80%20%3C%3C%20((len)%20%25%2032);x[(((len%20+%2064)%20%3E%3E%3E%209)%20%3C%3C%204)%20+%2014]%20=%20len;var%20a%20=%20%201732584193;var%20b%20=%20-271733879;var%20c%20=%20-1732584194;var%20d%20=%20%20271733878;for(var%20i%20=%200;i%20%3C%20x.length;i%20+=%2016){var%20olda%20=%20a;var%20oldb%20=%20b;var%20oldc%20=%20c;var%20oldd%20=%20d;a%20=%20md5_ff(a,%20b,%20c,%20d,%20x[i+%200],%207%20,%20-680876936);d%20=%20md5_ff(d,%20a,%20b,%20c,%20x[i+%201],%2012,%20-389564586);c%20=%20md5_ff(c,%20d,%20a,%20b,%20x[i+%202],%2017,%20%20606105819);b%20=%20md5_ff(b,%20c,%20d,%20a,%20x[i+%203],%2022,%20-1044525330);a%20=%20md5_ff(a,%20b,%20c,%20d,%20x[i+%204],%207%20,%20-176418897);d%20=%20md5_ff(d,%20a,%20b,%20c,%20x[i+%205],%2012,%20%201200080426);c%20=%20md5_ff(c,%20d,%20a,%20b,%20x[i+%206],%2017,%20-1473231341);b%20=%20md5_ff(b,%20c,%20d,%20a,%20x[i+%207],%2022,%20-45705983);a%20=%20md5_ff(a,%20b,%20c,%20d,%20x[i+%208],%207%20,%20%201770035416);d%20=%20md5_ff(d,%20a,%20b,%20c,%20x[i+%209],%2012,%20-1958414417);c%20=%20md5_ff(c,%20d,%20a,%20b,%20x[i+10],%2017,%20-42063);b%20=%20md5_ff(b,%20c,%20d,%20a,%20x[i+11],%2022,%20-1990404162);a%20=%20md5_ff(a,%20b,%20c,%20d,%20x[i+12],%207%20,%20%201804603682);d%20=%20md5_ff(d,%20a,%20b,%20c,%20x[i+13],%2012,%20-40341101);c%20=%20md5_ff(c,%20d,%20a,%20b,%20x[i+14],%2017,%20-1502002290);b%20=%20md5_ff(b,%20c,%20d,%20a,%20x[i+15],%2022,%20%201236535329);a%20=%20md5_gg(a,%20b,%20c,%20d,%20x[i+%201],%205%20,%20-165796510);d%20=%20md5_gg(d,%20a,%20b,%20c,%20x[i+%206],%209%20,%20-1069501632);c%20=%20md5_gg(c,%20d,%20a,%20b,%20x[i+11],%2014,%20%20643717713);b%20=%20md5_gg(b,%20c,%20d,%20a,%20x[i+%200],%2020,%20-373897302);a%20=%20md5_gg(a,%20b,%20c,%20d,%20x[i+%205],%205%20,%20-701558691);d%20=%20md5_gg(d,%20a,%20b,%20c,%20x[i+10],%209%20,%20%2038016083);c%20=%20md5_gg(c,%20d,%20a,%20b,%20x[i+15],%2014,%20-660478335);b%20=%20md5_gg(b,%20c,%20d,%20a,%20x[i+%204],%2020,%20-405537848);a%20=%20md5_gg(a,%20b,%20c,%20d,%20x[i+%209],%205%20,%20%20568446438);d%20=%20md5_gg(d,%20a,%20b,%20c,%20x[i+14],%209%20,%20-1019803690);c%20=%20md5_gg(c,%20d,%20a,%20b,%20x[i+%203],%2014,%20-187363961);b%20=%20md5_gg(b,%20c,%20d,%20a,%20x[i+%208],%2020,%20%201163531501);a%20=%20md5_gg(a,%20b,%20c,%20d,%20x[i+13],%205%20,%20-1444681467);d%20=%20md5_gg(d,%20a,%20b,%20c,%20x[i+%202],%209%20,%20-51403784);c%20=%20md5_gg(c,%20d,%20a,%20b,%20x[i+%207],%2014,%20%201735328473);b%20=%20md5_gg(b,%20c,%20d,%20a,%20x[i+12],%2020,%20-1926607734);a%20=%20md5_hh(a,%20b,%20c,%20d,%20x[i+%205],%204%20,%20-378558);d%20=%20md5_hh(d,%20a,%20b,%20c,%20x[i+%208],%2011,%20-2022574463);c%20=%20md5_hh(c,%20d,%20a,%20b,%20x[i+11],%2016,%20%201839030562);b%20=%20md5_hh(b,%20c,%20d,%20a,%20x[i+14],%2023,%20-35309556);a%20=%20md5_hh(a,%20b,%20c,%20d,%20x[i+%201],%204%20,%20-1530992060);d%20=%20md5_hh(d,%20a,%20b,%20c,%20x[i+%204],%2011,%20%201272893353);c%20=%20md5_hh(c,%20d,%20a,%20b,%20x[i+%207],%2016,%20-155497632);b%20=%20md5_hh(b,%20c,%20d,%20a,%20x[i+10],%2023,%20-1094730640);a%20=%20md5_hh(a,%20b,%20c,%20d,%20x[i+13],%204%20,%20%20681279174);d%20=%20md5_hh(d,%20a,%20b,%20c,%20x[i+%200],%2011,%20-358537222);c%20=%20md5_hh(c,%20d,%20a,%20b,%20x[i+%203],%2016,%20-722521979);b%20=%20md5_hh(b,%20c,%20d,%20a,%20x[i+%206],%2023,%20%2076029189);a%20=%20md5_hh(a,%20b,%20c,%20d,%20x[i+%209],%204%20,%20-640364487);d%20=%20md5_hh(d,%20a,%20b,%20c,%20x[i+12],%2011,%20-421815835);c%20=%20md5_hh(c,%20d,%20a,%20b,%20x[i+15],%2016,%20%20530742520);b%20=%20md5_hh(b,%20c,%20d,%20a,%20x[i+%202],%2023,%20-995338651);a%20=%20md5_ii(a,%20b,%20c,%20d,%20x[i+%200],%206%20,%20-198630844);d%20=%20md5_ii(d,%20a,%20b,%20c,%20x[i+%207],%2010,%20%201126891415);c%20=%20md5_ii(c,%20d,%20a,%20b,%20x[i+14],%2015,%20-1416354905);b%20=%20md5_ii(b,%20c,%20d,%20a,%20x[i+%205],%2021,%20-57434055);a%20=%20md5_ii(a,%20b,%20c,%20d,%20x[i+12],%206%20,%20%201700485571);d%20=%20md5_ii(d,%20a,%20b,%20c,%20x[i+%203],%2010,%20-1894986606);c%20=%20md5_ii(c,%20d,%20a,%20b,%20x[i+10],%2015,%20-1051523);b%20=%20md5_ii(b,%20c,%20d,%20a,%20x[i+%201],%2021,%20-2054922799);a%20=%20md5_ii(a,%20b,%20c,%20d,%20x[i+%208],%206%20,%20%201873313359);d%20=%20md5_ii(d,%20a,%20b,%20c,%20x[i+15],%2010,%20-30611744);c%20=%20md5_ii(c,%20d,%20a,%20b,%20x[i+%206],%2015,%20-1560198380);b%20=%20md5_ii(b,%20c,%20d,%20a,%20x[i+13],%2021,%20%201309151649);a%20=%20md5_ii(a,%20b,%20c,%20d,%20x[i+%204],%206%20,%20-145523070);d%20=%20md5_ii(d,%20a,%20b,%20c,%20x[i+11],%2010,%20-1120210379);c%20=%20md5_ii(c,%20d,%20a,%20b,%20x[i+%202],%2015,%20%20718787259);b%20=%20md5_ii(b,%20c,%20d,%20a,%20x[i+%209],%2021,%20-343485551);a%20=%20safe_add(a,%20olda);b%20=%20safe_add(b,%20oldb);c%20=%20safe_add(c,%20oldc);d%20=%20safe_add(d,%20oldd);}return%20Array(a,%20b,%20c,%20d);}function%20md5_cmn(q,%20a,%20b,%20x,%20s,%20t){return%20safe_add(bit_rol(safe_add(safe_add(a,%20q),%20safe_add(x,%20t)),%20s),b);}function%20md5_ff(a,%20b,%20c,%20d,%20x,%20s,%20t){return%20md5_cmn((b%20&%20c)%20|%20((~b)%20&%20d),%20a,%20b,%20x,%20s,%20t);}function%20md5_gg(a,%20b,%20c,%20d,%20x,%20s,%20t){return%20md5_cmn((b%20&%20d)%20|%20(c%20&%20(~d)),%20a,%20b,%20x,%20s,%20t);}function%20md5_hh(a,%20b,%20c,%20d,%20x,%20s,%20t){return%20md5_cmn(b%20^%20c%20^%20d,%20a,%20b,%20x,%20s,%20t);}function%20md5_ii(a,%20b,%20c,%20d,%20x,%20s,%20t){return%20md5_cmn(c%20^%20(b%20|%20(~d)),%20a,%20b,%20x,%20s,%20t);}function%20safe_add(x,%20y){var%20lsw%20=%20(x%20&%200xFFFF)%20+%20(y%20&%200xFFFF);var%20msw%20=%20(x%20%3E%3E%2016)%20+%20(y%20%3E%3E%2016)%20+%20(lsw%20%3E%3E%2016);return%20(msw%20%3C%3C%2016)%20|%20(lsw%20&%200xFFFF);}function%20bit_rol(num,%20cnt){return%20(num%20%3C%3C%20cnt)%20|%20(num%20%3E%3E%3E%20(32%20-%20cnt));}function%20str2binl(str){var%20bin%20=%20Array();var%20mask%20=%20(1%20%3C%3C%208)%20-%201;for(var%20i%20=%200;%20i%20%3C%20str.length%20*%208;%20i%20+=%208)bin[i%3E%3E5]%20|=%20(str.charCodeAt(i%20/%208)%20&%20mask)%20%3C%3C%20(i%20%25%2032);return%20bin;}function%20binl2hex(binarray){var%20hex_tab%20=%20%270123456789abcdef%27;var%20str%20=%20%27%27;for(var%20i%20=%200;%20i%20%3C%20binarray.length%20*%204;%20i++){str%20+=%20hex_tab.charAt((binarray[i%3E%3E2]%20%3E%3E%20((i%254)*8+4))%20&%200xF)%20+%20hex_tab.charAt((binarray[i%3E%3E2]%20%3E%3E%20((i%254)*8))%20&%200xF);}return%20str;}function%20mpwd_doIt(){var%20master=document.getElementById(%27masterpwd%27).value;if%20(master%20!=%20%27%27%20&&%20master%20!=%20null)%20{re%20=%20new%20RegExp(%27https*://([^/]+)%27);host%20=%20document.location.href.match(re)[1];var%20i=0,%20j=0,%20p=hex_md5(master+%27:%27+host).substr(0,8),%20F=document.forms;for(i=0;i%3CF.length;i++){E=F[i].elements;for(j=0;j%3CE.length;j++){D=E[j];if(D.type==%27password%27){D.value=p;D.focus();}if(D.type==%27text%27){if(D.name.toUpperCase().indexOf(%27PASSWORD%27)!=-1||D.name.toUpperCase().indexOf(%27PASSWD%27)!=-1){D.value=p;D.focus();}}}}}document.getElementsByTagName(%27body%27)[0].removeChild(document.getElementById(%27mpwd_panel%27));};function%20getPwdFld()%20{var%20L%20=%20document.getElementsByTagName(%27input%27);for%20(var%20i%20in%20L)%20{var%20nm%20=%20L[i].getAttribute(%22name%22)%20||%20%22%22;var%20tp%20=%20L[i].getAttribute(%22type%22)%20||%20%22%22;if%20((tp%20==%20%22password%22)%20||(tp%20==%20%22text%22%20&&%20nm.toLowerCase().substring(0,5)%20==%20%22passw%22))%20{return%20L[i];}}return%20null;}function%20panel()%20{var%20pwdTop%20=%200;var%20pwdLeft%20=%200;try%20{var%20obj%20=%20getPwdFld();if%20(obj.offsetParent)%20{while%20(obj.offsetParent)%20{pwdTop%20+=%20obj.offsetTop;pwdLeft%20+=%20obj.offsetLeft;obj%20=%20obj.offsetParent;}}}%20catch%20(e)%20{pwdTop%20=%2010;pwdLeft%20=%2010;}var%20div%20=%20document.createElement(%27div%27);div.style.padding=%274px%27;div.style.backgroundColor=%27yellow%27;div.style.border=%272px%20dotted%20red%27;div.style.position=%27absolute%27;div.style.top%20=%20pwdTop%20+%20%27px%27;div.style.left%20=%20pwdLeft%20+%20%27px%27;div.style.opacity=%27.9%27;div.setAttribute(%27id%27,%20%27mpwd_panel%27);div.appendChild(document.createTextNode(%27Master%20password:%20%27));var%20frm%20=%20document.createElement(%27form%27);frm.action=%27javascript:void(0);%27;div.appendChild(frm);var%20pwd%20=%20document.createElement(%27input%27);pwd.setAttribute(%27type%27,%27password%27);pwd.setAttribute(%27id%27,%27masterpwd%27);frm.appendChild(pwd);var%20ok%20=%20document.createElement(%27input%27);ok.setAttribute(%27type%27,%27submit%27);ok.setAttribute(%27value%27,%27OK%27);ok.onclick%20=%20mpwd_doIt;frm.appendChild(ok);document.getElementsByTagName(%27body%27)[0].appendChild(div);setTimeout(%22document.getElementById(%27masterpwd%27).focus();%22,%20333);};panel();})();

Rechtstaat und Demonstration

Ist schon etwas her, aber  fand ich trotzdem total spannend.

Immerhin, wer weiß wer demnächst noch alles demonstrieren muss?