Hash und Salt
Das Konzept von Salts ist eigentlich ein sehr einfaches. Da ich jetzt aber ein paarmal über Menschen gestolpert bin, denen das Konzept nicht klar wurde (und es auch selbst am Anfang für etwas hoch-komplexes hielt), versuche ich mich mal an einer einfachen Erklärung.
Funktionsweise
Angenommen, man hat eine Webanwendung, in die sich Leute mit einem Passwort einloggen können (sie könnte Serendipity heißen). Selbstverständlich speichert man das Passwort dieser Nutzer nicht im Klartext ab, weil dann ein einfacher Blick in die Datenbank genügen würde, um das Passwort zu verraten. Stattdessen speichert man den Hash H des Passworts, der durch eine beliebige kryptographische Hashfunktion generiert wird:
H = hash(Passwort)
hash() ist im wesentlichen eine Einwegfunktion, also kann aus H nicht direkt Passwort rekonstruiert werden. Es existiert kein unhash(H) == Passwort.
Bei einem Loginversuch mit dem Passwort wird dann das Hashen wiederholt und mit dem gespeicherten H in der Datenbank verglichen:
bool loginCorrect?(passwort) { return (hash(passwort) == H) }
Nur wenn die beiden Hashes übereinstimmen, stimmen die durch die Hashes repräsentierten Passwörter und der Nutzer kann sich erfolgreich einloggen.
Nun kommt der Salt dazu. Der wird zufällig gewählt, ist also eine zufällige Zeichenfolge, und wird dem Passwort angehängt:
hash(Passwort + Salt) = salted_H
Das wird nun bei jeder Passworterstellung gemacht, also insbesondere jedes Mal ein neuer Salt berechnet. Vom Prinzip her ist das alles.
Der Salt wird natürlich mit dem salted_H in der Datenbank gespeichert. Das ist notwendig, denn bei einem Loginversuch wird ja wieder ein Hash berechnet und mit dem gespeicherten verglichen:
bool loginCorrect?(passwort) { return (hash(passwort + Salt) == salted_H) }
Warum?
Bleibt die Frage, warum man einen solchen Salt nutzen sollte. Die Antwort: Sicherheit. Es soll verhindert werden, dass aus den Hashes indirekt das Passwort berechnet werden kann. In der Konsequenz geht es um ein Gegenmittel gegen Rainbow-Tables.
Die Datenbank der Webanwendung könnte gestohlen werden, wie das ja in letzter Zeit reihenweise passierte. Ziel des Angreifers ist es danach, das Passwort im Klartext herauszufinden. Aus zwei Gründen:
- Wenn er nur die Datenbank hat, könnte er sich dann in der Webanwendung einloggen und Aktionen durchführen
- Viele Nutzer verwenden Passwörter mehrfach, sodass der Angreifer bei vielen anderen Diensten gültige Logins und Passwörter bekommen würden
Im Idealfall hat der Angreifer bisher nur die Datenbank mit dem Nutzernamen (der natürlich auch gehasht werden könnte), dem salted_H und dem Salt jedes Nutzers. Schon dank des Hashens reicht das nicht, um sich einzuloggen. Denn die Loginfunktion hasht ja wieder, gibt man den salted_H da ein entsteht also:
return (hash(salted_H + Salt) == salted_H))
Auch ohne den Salt wäre das false, denn man kann davon ausgehen, dass hash(hash(X)) != hash(X).
Ohne den Salt würde der Angreifer jetzt versuchen, eine Rainbow-Table aufzubauen. Dafür nutzt er seinen privaten Rechencluster in etwa so:
1000000000.times { passwort = guess_password() rainbow_table[hash(passwort)] = passwort }
Er erstellt also eine Liste von gehashten Passwörtern und ihrem Klartext. Danach braucht er nur in der Datenbank zu schauen, ob der Hash verwendet wurde, und weiß deswegen, welches Passwort verwendet wurde um den Hash zu erstellen. Schon hat er das Passwort im Klartext.
Genau das verhindert der Salt. Da zwei Datenbanken oder sogar zwei Nutzer in einer Datenbank unterschiedliche Salts benutzen, unterscheidet sich ihr salted_H, selbst wenn sie das gleiche Passwort benutzen. Wird also eine Datenbank gestohlen, muss zwingend für jeden einzelnen Nutzer geguckt werden, ob
hash(guess_password() + Salt) == salted_H
gilt. Eine Rainbow-Table, die die Salts mitspeichert würde absurd groß werden:
for salt in salts { 1000000000.times { passwort = guess_password() rainbow_table[salt][hash(passwort +salt)] = passwort } }
Daher kommt auch die Bewegung, teure Hashfunktionen wie bcrypt zu nutzen und sie möglichst noch mehrmals durchlaufen zu lassen. Bei einem Login ist die benötigte Zusatzzeit kaum bemerkbar, aber bei einem Knacken der Hashes tut jede ms weh.
Kurz
Ein Hash mit Salt ist einfach hash(X + Salt). Er schützt nicht generell vor schwachen Passwörtern, aber er erschwert es, dass Passwörter aus dem Hash rekonstruiert werden können.
Aufmerksamkeitsheischend
Auf HN ist gerade ein Artikel von kissmetrics über den Wert von Bildern in Artikel. Gar nicht völlig uninteressant. Aber ironisch, wie nervig/schlecht die Seite selbst ist, auch ohne Artikelbilder. Ich habe mal alle Bereiche markiert, die Aufmerksamkeit fordern:
Keine Popups, keine eigentliche Werbung außer dem Selbstwerbebanner, nichts blinkendes. Einzig das rechte Mail-Newsletter-Widget taucht nachträglich auf und verletzt damit die "Keine Bewegung bei Texten"-Regel. Nichts schreit wirklich, von der Grund-Farbwahl sympathisch dezent - trotzdem völlig überfrachtet und äußerst beängend. Und ich sehe erst auf dem Screenshot, dass die Seite durch den Unsinn auch noch unwuchtig wird.
Social-Peinlichkeiten wie diese zerstören ganze Designs.
ShareLatex
Via Dirk hatte ich ShareLaTeX für die nächste Arbeit im Hinterkopf vorgesehen, und diese eben damit geschrieben. Funktionierte hervorragend.
- Es waren alle Latex-Pakete da, die ich brauchte
- Bibtex ist dabei
- Der PDF-Export funktioniert
- Die Vorlage war hilfreich, es fehlt nur \usepackage[utf8]{inputenc}
- Der Editor selbst hat nur eine Macke (manchmal akzeptierte er kein Bewegen des Cursors per Pfeiltasten)
Ich habe hier zwar Latex noch von der Bachelorarbeit halbwegs eingerichtet, aber so war das definitiv einfacher.
Das darfst du nicht
If you give permission, you are temporarily given the rights of an administrator to complete the task and then your permissions are returned back to that of a standard user.
Smartifiziert das Backend
Für Serendipity 2.0 ist eines der Ziele ja ein neugestaltetes Backend. YellowLed arbeitet wohl auch derzeit mit Helfern an einem Prototypen dafür. Um den am Ende auch umsetzen zu können dürfte es nötig sein, den HTML-Code anzupacken, den Serendipity im Backend ausspuckt. Im Gegensatz zum Frontend nutzt das Backend keine Templates, da ist also wild HTML mit PHP vermischt.
Gerade wenn es um so grundlegende Dinge geht wie HTML 5, Div- vs Tabellenlayouts oder auch inline-CSS, ist das keine gute Ausgangsposition.
Deswegen sollte das Backend Smarty nutzen. Dafür muss man mindestens die Dateien in include/admin/ durchgehen und dort alles, was direkt ausgegeben wird, abfangen und stattdessen an eine Template-Datei übergeben (mindestens, weil es sein könnte, dass später noch Teile des Kerns dazukommen wie serendipity_showPlugins, die an anderer Stelle beheimatet sind).
Das ist eher zeitaufwändig als dass es schwer ist, zumindest solange es so wie bisher nur um die Grundlage der Trennung zwischen Logik und Ausgabe geht, nicht um Feinheiten. Kleinere Bugs sind in der Phase auch noch nicht schlimm, soll das Backend ja sowieso noch überarbeitet werden. Insbesondere kann jeder helfen, der mit Smarty zurechtkommt, dem aber PHP eher fremd ist.
Ich habe in loser Absprache im Forum eine Liste zum Koordinieren und zur Fortschrittsanzeige und im git-Repository einen passenden branch angelegt. Es sind 16 Dateien mit insgesamt 5276 Zeilen, wovon viele Teil von Funktionen sind, die nur eine Statuszeile am Ende ausgeben. Zwei Dateien sind bereits abgearbeitet.
Genug Arbeit für einen, aber schnell erledigt wenn ein paar Leute mithelfen.
Manipulation
Mit einer kilometerlangen Menschenkette gedenken Tausende Dresdner dem Jahrestag der Zerstörung ihrer Stadt und setzen ein Zeichen gegen Rechts - der Neonazi-Aufmarsch wird vorzeitig abgebrochen, Polizisten eskortieren die Rechtsextremen zurück zum Bahnhof. Ausschreitungen bleiben aus.
Das ist der Teaser zum Spiegelartikel über den Naziaufmarsch in Dresden. Das ist, was passierte. Inhaltlich sagt der Spiegelartikel selbst nichts anderes.
Genau das gleiche Schema wie vor zwei Jahren.
Gettext - export TEXTDOMAIN
Mit gettext Skripte zu übersetzen war mir immer etwas unangenehm. Eigentlich finde ich es unschön, die kompilierten .mo-Dateien mit den ansonsten komplett lesbaren Skripten zu vermischen. Andererseits ist $"labelId" schon ein guter Weg, Übersetzungen im Code zu haben. Für izulu wollte ich das mal richtig machen, anstatt wie früher wieder ein eigenes System zu nutzen (je nach Sprache eine andere Datei mit Variablen per source einlesen). Wenn ich direkt an das export denke wird es das nächste mal auch wesentlich angenehmer .
Der Guide erwähnt es zwar, aber verschluckt die Befehle:
Place the resulting localized.sh.mo file in the /usr/local/share/locale/fr/LC_MESSAGES directory, and at the beginning of the script, insert the lines:TEXTDOMAINDIR=/usr/local/share/locale TEXTDOMAIN=localized.sh....
The TEXTDOMAIN and TEXTDOMAINDIR variables need to be set and exported to the environment.
Also:
TEXTDOMAIN="izulu" TEXTDOMAINDIR="/usr/share/locale/" export TEXTDOMAIN export TEXTDOMAINDIR
Ich hatte mit der Syntax gekämpft, um den Inhalt einer Variable als msgid zu nutzen. Letzten Endes bin ich bei dem expliziten gettext-Aufruf gelandet:
notify-send "izulu" "$(gettext "$1")"
Durch das vergessene export funktionierte dies anfangs nicht.
Stolz
Todd Howard (Skyrim) hielt die sehenswerte DICE 2012 Keynote über Spieledesign.
League of Legends - Tipps
Ein kleiner Guide, um in LoL (unranked) zu den besseren Spielern zu gehören. Wer das Spiel eine Weile kennt, dem sollte das alles klar sein. Aber wer gerade erst die Grundlagen gelernt hat, kann hiermit vielleicht etwas anfangen.
Lerne einen Helden richtig
Taktik hin oder her, wer den eigenen Helden nicht beherrscht wird unnötig oft sterben. Es macht einen gewaltigen Unterschied, wenn man genau weiß, wie weit über den Pfeil hinaus Mundos Axt fliegt oder wie weit der Trefferbereich von Morganas Stun ist. Sicher ist es sinnvoll, jeden Helden einmal angespielt zu haben, aber sobald der erste Held gefällt sollte man sich diesen als Main erwählen, ihn kaufen und regelmäßig mit ihm spielen.
Habe ein Repertoire
Mag ein Widerspruch zur oberen Faustregel stehen, ist aber wichtig. In LoL gibt es typische Rollen:
- Helden, die Schaden mit AP machen (AP-Caster)
- Helden, die Schaden mit AD machen (AD-Carries)
- Assassinen
- Supporter
- Tanks
Über die richtige Teamaufstellung kann man sich streiten, aber es ist ziemlich offensichtlich eine schlechte Idee, ein Team rein aus AP-Castern aufzustellen - die Gegner werden einfach Magieresistenz kaufen und gewinnen. Also sollte jeder Spieler ein paar verschiedene Typen von Helden beherrschen, um nicht immer seinen Main und damit schlimmstenfalls den fünften AD-ler wählen zu müssen.
Sei der Tank
Das Team ohne Tank verliert. Will also partout kein anderer den Tank wählen, dann spiel ihn halt selbst. Das kann mit einem schlechten Team ziemlich deprimierend sein, mit einem ordentlichen dagegen ziemlich toll: einen erfolgreichen Teamfight zu initiieren macht Spaß. In fast jedem Spiel gibt es die Phase nach dem Lanen, in der sich die beiden Teams in der Mitte gegenüber stehen. Es ist dann der Tank des Teams, der entscheiden muss, in welchem Moment er auf die Gegner zustürmt und darauf vertraut, dass er lange genug die Gegner beschäftigt, bis sein Team sie erledigt hat.
Deprimierend, wenn das Team nicht mitzieht. Aber Tank sein ist eine gute Übung, denn irgendwann bekommt man ein Gefühl dafür, welche Situation die richtige zum Angriff ist.
Sowieso sind einige Tanks ziemlich cool.
Folge dem Tank
Initiiert der Tank oder versucht er, eine Gruppe zusammenzubekommen, dann folge ihm. Der Tank ist wichtig für den Gruppenkampf, ohne ihn wird das eh nichts, aber nur wenige Tanks haben alleine eine Chance (wobei man da vorsichtig sein muss, Riot hat inzwischen einige Tanks gebaut, die auch ordentlich austeilen).
Sage Misses an
Wahrscheinlich die wichtigste Regel. Erfahrene Spieler können selbst etwas auf die Map achten und so einen Miss mitbekommen, aber eigentlich reicht dafür die Aufmerksamkeit seltenst aus. Ein "ss" oder "top/bot miss" oder ein passender Ping auf den Fluss sollte immer kommen, wenn man realisiert, dass einer der Gegner fehlt. So bekommen die anderen die Gelegenheit, sich zum Tower zurückzuziehen, bevor der Gegner aus dem Gras stürmt.
Warde
Wards sind wichtig. Ohne Wards steht man auf der Lane plötzlich drei Gegnern gegenüber, drei Ganks später ist das Spiel vorbei. Eigentlich ist es Aufgabe des Supporters, Wards zu kaufen, aber der kann nicht überall sein. Im Zweifel also selbst kaufen, gerade als Schutz vor dem Gegner in der Mitte oder vor dem Jungler. Typischerweise leveln Jungler so schnell wie die Helden auf einer Zweier-Lane (das war früher anders) und ganken ab Stufe 4, also sollte da so langsam der erste Ward stehen.
Gute Positionen sind diese:
Alternativ kann man den Ward auch in das Gras beim Flussausgang stelle, aber etwas weiter oben sieht man direkt den Waldeingang bzw. den kleinen Drachen mit und hat etwas mehr Zeit, um zu reagieren.
Richtig Farmen
Stichwort ist lasthitten. Es ist Verschwendung, am besten noch Fähigkeiten gegen die Creeps einzusetzen und dann kein Gold zu bekommen, weil ein Creep den letzten Schlag getan hat. Noch dazu kommt man so näher an den gegnerischen Tower, also wird der eigene Fluchtweg länger. S drücken, um das automatische Angreifen zu stoppen, und die Creeps nur so angreifen, dass man das Gold bekommt. Im Zweifel ist das spielentscheidend.
Blinke
Der Beschwörerzauber Blink (Flash) ist fast immer die beste Wahl. Er bringt Geschwindigkeit ins Spiel. Schnell hinter den Gegner herblinken, um ihn doch noch zu erwischen, oder mit Blink über eine Wand fliehen oder aus Veigars Stunkreis heraus - lohnt sich immer.
Genauso wichtig ist es, die eigenen Fähigkeiten genau zu kennen. Tryndamere z.B. kommt mit seiner Drehattacke durch erstaunlich viele Hindernisse, Tristana springt über einige Mauern problemlos drüber, Fiddlesticks Ulti teleportiert ihn über jedes Hindernis hinweg, usw.
Es gibt keinen Killsteal!
Völlig egal was passiert, wer "KS!" brüllt hat keine Ahnung. Genauso dequalifizierend wie sich über Ganks aufzuregen. LoL ist ein Teamspiel, es ist immer wichtiger, den Gegner wirklich zu erwischen oder zu versuchen, zumindest einen Assist zu bekommen, als den falschen Stolz irgendeines Kiddies zu befördern.
Passiert gerade am Anfang, in den unteren Elo-Ebenen, immer wieder, und ist jedes mal eine gute Gelegenheit, sich über die per Tab erreichbare Ignorierfunktion zu freuen.
Tastaturen
Gestern glaubte ich, meine Tastatur geschrottet zu haben (merke: mehr Geduld nach dem Spülen beweisen). Sie hat es aber natürlich doch gut überstanden. Da ich das gestern abend noch nicht wusste, habe ich ein paar Stunden nach guten Tastaturen gesucht, während meine neben der Heizung trocknete. Meine bisherige Tastatur ist übrigens eine völlig normale Cherry-Tastatur, mit der ich komplett zufrieden bin - vor allem, nachdem sie nun wieder sauber ist.
Damit meine Recherche nicht verloren ist, falls ich doch mal eine neue brauche:
Technik
Gerade kommen wohl mechanische Tastaturen im Mainstream an. Wohl konsequent, die Industrie versucht seit Jahren, für Tastaturen möglichst viel Geld zu verlangen und rechtfertigt das bei Gamern mit Zusätzen wie Displays, Makrofunktionen und USB-Hubs, was an potentiellen Kunden wie mir völlig vorbeigeht. Höchstens leuchtende Tasten könnten nachts manchmal praktisch sein. Mir geht es ums Tippen und nur nebenbei ums Spielen, wofür ich keine spezielle Tastatur brauche. Genau für das Tippen sollen mechanische Tastaturen besser sein, was eventuell einen höheren Preis rechtfertigt.
Unterschied zwischen mechanischen Tastaturen und üblichen ist, wie die Tasten funktionieren: bei normalen Tastaturen drücken die Tasten auf eine Folie und schließen dadurch einen Kontakt, bei mechanischen ist unter jedem Knopf ein Schalter. Das sind wohl praktisch immer die Cherry MX-Schalter, die es in drei Ausführungen (vereinfacht, der erste Link erklärt mehr als umfassend) gibt:
MX Black
Linearer Druck, also kein (zusätzlicher) Klick beim Auslösen.
MX Brown
Sanfter Klick beim Auslösen (taktil), ein Mittelding zwischen den beiden anderen.
MX Blue
Starker Klick beim Auslösen (taktil), damit angeblich nahe am Schreibgefühl einer alten IBM-Tastatur.
Wenn eine mechanische Tastatur, dann scheint die Faustregel zu sein: Für Hardcore-Spieler MX Black, für Nur-Schreiber MX Blue, für den Rest MX Brown. In Wirklichkeit muss es aber wohl stark von der Gewöhnung abhängen, welches Schreibgefühl man gut findet.
Mechanisch?
Ich finde, man muss da mit der Bewertung ein bisschen aufpassen: Großer Vorteil der mechanischen Tastaturen soll beispielsweise die Haltbarkeit sein. Mag unter Laborbedngungen stimmen, aber es ist ja nun wirklich nicht so, als ob eine halbwegs anständige normale Tastatur jede zweite Woche ersetzt werden muss. Bevor eine Tastatur kaputtgeht ist normalerweise das Plastik verschimmelt.
Es ist also kein Zufall, dass Hardcore-Gamer angesprochen werden, z.B. mit der BlackWidow Ultimate. Man kann so tun, als würden vermeintlich bessere Tastaturen bessere Chancen beim Spielen bieten und darüber einen höheren Preis verlangen, am liebsten dann die Tastatur mit sinnlosem Zusätzen vollstopfen und nochmal mehr Geld verlangen.
Wobei das ein bisschen unfair ist, mechanische Tastaturen als Nischenprodukte waren die letzten Jahre immer teuer und werden durch die neuen Produkte insgesamt scheinbar eher billiger. Es ist wohl eher so, dass über die Masche Gamer-Tastaturen nochmal teurer wurden.
Für mich kommt also beides in Frage, ich bin nicht davon überzeugt, dass eine mechanische Tastatur im Vergleich zu einer guten normalen soviel besser ist, dass sie den hohen Preis rechtfertigt - erst recht nicht, wenn man eine normale Tastatur gewöhnt ist. Aber ich bin gerne bereit, das auszuprobieren, denn immerhin schreibe ich ziemlich viel und würde deswegen durch eine bessere Tastatur, die mir das Tippen einfacher macht, erheblich profitieren.
Auswahl
Ich habe also eine Reihe von Tastaturen in Betracht gezogen. Gesucht war eine perfekt zum Schreiben und zum regelmäßigen Spielen ohne Ehrgeiz geeignete, idealerweise mit Tastenbeleuchtung, wobei durch den hellen Monitor hier sowieso auch nachts eine Schreibtischlampe an und die Beleuchtung momentan entsprechend unwichtig ist. Wie immer: selbstverständlich ohne Klavierlack.
Trotzdem fast ernsthaft in der Auswahl wäre die Gigabyte Aivia K8100 in knallgelb oder rot, die finde ich so abgefahren, dass ich sie gerne gehabt hätte, obwohl die Tastatur natürlich gleichzeitig auch ziemlich hässlich ist. Gamestar fand die Aivia aber gar nicht gut. Einer eher ernsthafte Alternative und ebenfalls mit leuchtenden Tasten wäre das Logitech Illimunated Keyboard - das kurze Review liest sich halbwegs echt und positiv, aber eigentlich mochte ich das Tippgefühl von Logitech-Tastaturen noch nie. Sähe aber so gut aus, dass man es ausprobieren könnte.
Wäre es eine mechanische Tastatur geworden, wäre für mich wahrscheinlich eine mit MX Brown-Schaltern am besten geeignet (da Programmierer und Spieler). Dann gibt es gar nicht so viel Auswahl. Da wäre zum einen die Zowie Celeritas, aber sie ist mir zu teuer. Alternative ist die deutlich billigere Cherry G80-3000, die es in allen Varianten gibt, also mit allen drei Schaltern. Von ihr war Gamestar zwar ebenfalls nicht wirklich begeistert, aber aufgrund meiner guten Erfahrungen mit der Firma würde ich den Test da einfach mal nicht beachten. Man muss nur beim Kauf ziemlich aufpassen, viele Shops weisen nicht aus, welche Schalter benutzt wurden, also welche Variante des Keyboards genau verkauft wird. Steht zumindest der Versionsname dabei, kann man mit diesem PDF prüfen, welche Version welche Schalter nutzt (Linear=MX Black, Soft Pressure Point=MX Brown, Click Pressure Point=MX Blue), eine LQCDE wäre es also die richtige.
Wahrscheinlich hätte ich mit der mechanischer Cherry-Tastatur meine Cherry-Tastatur ersetzt, oder einfach die alte nicht-mechanische nochmal gekauft.
Bayes 0.4.6: Backend-Verbesserungen
Nachdem im Forum Verbesserungen für das Bayes-Plugin vorgeschlagen wurden, habe ich mich wirklich mal an das Backend gesetzt. Erstens ist es jetzt komplett smartifiziert. Zweitens wurde der Papierkorb überarbeitet. Und Drittens wurden einige kleine Verbesserungen eingebaut. Als Überblick:
-
Die Tabelle im Datenbankmenü war vorher blind auf 2000 Einträge beschränkt, damit das Einfärben der Zeilen nicht den Browser lahmlegte. Nun ist sie paginiert.
-
Die meisten sichtbaren Änderungen gibt es beim Papierkorb. Die wichtigste: Er ist nun durchblätterbar. Auch bei ihm bestand das Problem, dass er schlicht zu voll werden konnte und dann den Browser lahmlegte. Außerdem werden jetzt nur die sichtbaren Kommentare gelöscht und nicht blind alle. Statt der alten Tabelle wird jeder Kommentar nun in Listenform präsentiert und die Liste über detail/summary ausklappbar gemacht (mit polyfill für alle Browser außer Chrome, nur er kennt bereits das Element). Dadurch war auch genug Platz, Roberts Wunsch umzusetzen und den zugehörigen Artikel zu verlinken, und Grischas Wunsch zufolge wird die Kommentarbewertung angezeigt.
- Die Email-Benachrichtigung sollte zwischen den beiden Links den Text "Kommentar bewilligen und als valid markieren" anzeigen. Der wurde vorher verschluckt.
- Das Menü wird nur noch angezeigt, wenn der Nutzer die Rechte "adminComments" hat. Vorher war auch ohne dieses Recht das Menü sichtbar, aber die Aktionen wurden blockiert.
Nebeneffekt der Aktion ist, dass die serendipity_event_spamblock_bayes.php nun 200 teils sehr hässliche Zeilen weniger hat und damit wieder unter die 2000-Zeilen-Marke gerutscht ist. Der ganze HTML-Code gehört da auch wirklich nicht hin. Und durch die Templatisierung ist jede folgende Änderung einfacher.
Es wurde also doch nicht der komplette Umbau des Backends, den ich eine Weile in Betracht gezogen hatte, aber ich hoffe, durch die Änderungen ist nun alles etwas runder.
Bayes-Menü
Ich bin am überlegen, es rauszunehmen. Deswegen: Hat jemand von denen, die das Plugin nutzen, je das erste Untermenü "Lernen" genutzt?
Zweifel
Googles Motto sei "Don't be evil". Tolles Motto, und ich mag Google. Email, RSS, Musik, Websuche: Klar hab ich mir Alternativen angeschaut, insbesondere duckduckgo als Suchmaschine, aber doch läuft ein großer Teil meines Internetlebens über Google. Ich könnte mir sogar gut vorstellen, mal für die Firma zu arbeiten.
Dementsprechend beobachte ich ziemlich genau den Meinungsumschwung in der Technikgemeinde. In Deutschland wird Google ja schon ewig als Datenkrake angefeindet, z.B. als völlig absurde Vorwürfe wegen Streetview laut wurden. Sehr laut. Neu ist aber, dass man inzwischen öfter von technikaffinen (via) über Zweifel an Googles Integrität liest. Und bei solchen Plänen ist das wohl auch kein Wunder. Trotzdem: Wenn ich sowas lese, ist da immer im Hinterkopf, dass Google Gründe für alles haben wird. Dass das Motto noch steht. Dass die Integration der Dienste an sich eine gute Sache ist, auch wenn ich nicht mit Klarnamen in Google+ stehen will.
Es ist für sich genommen eine kleine Sache, die dann auch bei mir Zweifel an Google aufkommen lässt. Die kleine Linkbox an der Seite, die inzwischen über Googles +1-Button gefüllt wird, blieb plötzlich einfach leer. Das war ja eine etwas wackelige Yahoo-Pipes Lösung. Google hat die +1-Seite geändert, also musste die Pipe angepasst werden. Soweit ist das normal und eben der Preis, wenn man direkt die Seite abgreift.
Nur: Was ist das überhaupt für eine chaotische Seite? Für mich sieht das so aus, als würde Google da absichtlich seinen Quellcode obfuscaten, also möglichst unleserlich machen. Vielleicht sind das Geschwindigkeitsoptimierungen, aber das Ergebnis ist grausam.
<table id="1/h1ubcw1u5wrq2vnig5qamwvo5traysnghxnrafnjidnmyw3jihu2yglka4t2yg1l5wsnifvmhxurcufigpqq2wvdgwqrasvcidoqesn5hsqrauf55pkqwwv3h1qamtfngpracff5h5raeff1htxaeufbgoqqitfbgpr2ut31igqqwuf5glmr4tv5ihlqkv31gxmqwtdhhxsagtfm5w/" class="mUm4rc kM5Oeb-Zj2Mze"aria-live="polite"> <tr> <td class="I3d9Ld f0f5Be" align="center"> <div aria-hidden="true" class="wBz4Ye"> <a href="http://annalist.noblogs.org/post/2012/01/17/routinemasig-schrieben-sie-anschliesend-eine-anzeige-gegen-das-niedergeschlagene-opfer/"/>
Klassennamen, die aussehen wie die Hashs richtiger Namen? Eine überlange id? Alles in einem Quellcode, dem natürlich die Zeilenumbrüche wegoptimiert wurden. Dazu oben im head der Seite der unlesbare Javascript-Codeblock.
Ich erinnere mich an einen Artikel, in dem Google als Suchmaschine empfohlen wurde, schon weil der HTML-Code der Suchstartseite so schön war. Minimal, sie bestand nahezu nur aus einem div für die Suchbox, was man durch irgendein Visualisierungstool - um das es eigentlich ging, wahrscheinlich war es dieses - gut sehen konnte. Von dieser Schönheit im Code ist Google nun weit entfernt (Edit: Wobei sich im gesamten für die Startseite immer noch ein schön kleiner Graph ergibt).
Für sich genommen ist dieser Wandel kein Problem. Dann sind es eben mehr Funktionen geworden, dadurch mehr Code, und wird eben auf Kosten der Lesbarkeit optimiert. Aber zusammen mit dem Ärger darüber, dass Google nicht von sich aus einen RSS-Feed der eigenen +1-Items anbietet (oder gibt es sowas etwa und ich kenne es nur nicht?), ergibt sich kein schönes Gesamtbild.