Stranger Than Usual

Entengrütze

Heute war ich mal wieder im botanischen Garten der RUB. Da gibt es auch einige Anlagen für Wasserpflanzen. Die meisten sind gezielt bepflanzt, andere werden momentan anscheinend nicht aktiv genutzt. Das hier ist eine davon:

Ein rechteckiger Teich, der komplett mit Entengrütze bedeckt ist. Im Vordergrund ein Schild: „Offene Wasserfläche VORSICHT“.

Der Wasserspiegel ist fast auf einer Höhe mit dem Boden drumherum, das Ding ist komplett bedeckt mit Entengrütze (auch als Wasserlinsen bekannt). Auf einen flüchtigen Blick erkennt man sie also nicht als Wasserflächen, deswegen die Warnschilder.

Ein paar Minuten, nachdem ich an diesem Teich vorbeigekommen bin, hörte ich Stimmen und Geräusche:

„Halt ihn fest, das ist Wasser!“ (lautes, platschendes Geräusch) „Hohl in raus, HOHL IHN RAUS!“ (weiter platschendes Geräusch) „Er ist ganz nass!“.

Ich habe die Szene nicht gesehen, aber ich habe ein ziemlich genaues Bild davon, was dort passiert ist :)

Die irreführende Fahrradampel

Ein nennenswerter Teil meiner Mobilität besteht aus Fahrradfahren. So fahre ich zum Beispiel zum Einkaufen oft mit dem Fahrrad. Besonders, wenn der Supermarkt, zu dem ich will, etwas weiter weg liegt. Radfahren ist aber nicht immer ohne Probleme. Eins davon ist die Kreuzung Ardeystraße / Johannisstraße in Witten:

Eine Kreuzung zweier mehrspuriger Straßen. Der Beobachter steht auf dem Bürgersteig an einer Ecke der Kreuzung. Auf der Kreuzung sind in Rot Radwege eingezeichnet. Für jede Richtung gibt es eine Einbuchtung für indirektes Linksabbiegen.

Diese Kreuzung legt den Radfahrer_innen indirektes Linksabbiegen nahe. Das Konzept kenne ich schon länger, den Begriff habe ich erst durch Recherchen zu diesem Artikel kennengelernt. Indirektes Linksabbiegen bedeutet, dass man an der Kreuzung zunächst geradeausfährt und sich dann in die Spur, die von rechts kommt, einsortiert. Der Vorteil ist, dass man ein direktes Linksabbiegen vermeiden kann, was je nach Kreuzung und Verkehrslage wirklich gruselig sein kann. Der Nachteil ist, dass man zwei Ampelphasen warten muss.

In diesem Fall kümmern mich aber weder der Vorteil noch der Nachteil, sondern die konkrete Umsetzung. Ich hätte hier eine Luftaufnahme, aber die ist von Google Maps. Google erlaubt zwar die nicht-kommerzielle Nutzung unter korrekter Quellenangabe, aber das Internet™ gibt unklare Auskünfte darüber, wie es mit Luftaufnahmen aussieht, die Google von Drittparteien lizenziert hat. Also stattdessen eine Art abgepaustes SVG der Kreuzung. Die Zahlen und Pfeile werden weiter unten erklärt:

Abstrakte Skizze der Kreuzung aus dem Foto oben. Die Kreuzung ist X-förmig. Rot eingezeichnet sind die auf dem Foto oben zu sehenden Fahrradstreifen. Ein grüner Pfeil zieht sich durchs Bild. Er beginnt an einer Straße unten links (markiert mit einer 2), führt über die Kreuzung zu einer der Einbuchtungen zum indirekten Linksabbiegen (markiert mit einer 3) und zeigt am Ende in die Straße links oben. Die Straßenecke rechts ist markiert mit einer 1, die Straßenecke oben ist markiert mit einer 4.

Das Foto oben ist (wie die anderen Fotos in diesem Post) von der mit einer grünen 1 markierten Stelle aufgenommen. Der grüne Pfeil zeigt einen Weg, den man zum Linksabbiegen nehmen kann. Ich fahre dort also erst einmal von Position 2 geradeaus und reihe mich dann entsprechend dem Abbiegepfeil bei 3 zum Linksabbiegen ein. Ich will, sobald meine Ampel grün wird, nach obenLinks fahren, also richte ich mich entsprechend aus. Nun ist die eigentliche Ampel für diese Kreuzung hinter mir, ich kann also nicht sehen, wann ich losfahren darf. Aber kein Problem, denn bei 4 ist eine Fahrradampel (hier fotografiert vom Bürgersteig, nicht von der Straße, als Abbieger mit dem Fahrrad stehe ich links des Bildausschnittes.):

Ein Fußgängerüberweg an einer Kreuzung. In der Mitte des Bildes, auf der gegenüberliegenden Straßenseite, steht eine Fahrradampel.

Also warte ich darauf, dass die Ampel grün wird. Es wird grün für die Fußgängerampel. Es wird grün für die Autofahrer hinter mir. Es wird grün für die Abbieger. Nur für mich wird es nicht grün, obwohl alle anderen, die in die gleiche Richtung wollten, schon grün hatten. Endlich wird sie grün! Ich fahre los. Komme über die Kreuzung, muss aber hart bremsen, weil die Fußgänger quer zu mir gleichzeitig grün haben. Und nicht nur das. Nur Momente danach braust hinter mir der Querverkehr vorbei.

Ich steige ab und rette mich mit dem Fahrrad auf den Gehweg. Während ich noch über die komische Ampelschaltung schimpfe, merkt ein Passant an, dass diese Kreuzung dafür sogar schon mal in der Zeitung stand.

Die richtige Ampel für mich war nämlich nicht die Ampel bei 4. Es wäre eine Ampel bei 1 gewesen:

Eine Fahrradampel in Nachaufnahme. Die Ampel ist rot. Über dem roten Ampellist ist ein weiteres Ampelelement mit einem blass weiß leuchtenden Pfeil.

Wenn man genau hinschaut, sieht man sogar den Pfeil, der nach links zeigt. Die Ampel hat nur ein Problem: Wenn ich micht korrekt eingeordnet habe, ist die Ampel rechts hinter mir, ungefähr auf 4 Uhr. Da sehe ich sie nicht. Stattdessen sehe ich die Ampel gegenüber, die genau in meine Richtung ausgerichtet ist. Den blassen weißen Pfeil nach links kann man schnell übersehen. Immerhin sind die einzigen anderen weißen Lichtsignale im Straßenverkehr ausschließlich für öffentliche Verkehrsmittel.

Keine Ahnung, wer das für eine gute Idee gehalten hat. Die Kreuzung, wie sie jetzt ist, ist noch relativ neu. Die WAZ hat sie „Wirrwarrkreuzung“ genannt, in einem Artikel, den ich nicht verlinke, weil man den Artikel nicht lesen kann ohne seine Seele zu verkaufen.

Ein Fahrradblogger aus der Nachbarstadt Bochum hingegen meint in einem Blogpost, diese Kreuzung in Witten sei korrekt nach Empfehlungen angelegt worden. In dem Artikel beklagt er sich über Kreuzungen mit indirektem Linksabbiegen, in denen es für Radfahrer_innen extrem schwierig gemacht wird, das richtig zu machen.

Aber Empfehlungen hin oder her, ich finde diese Ampeln extrem verwirrend und wäre beinahe überfahren worden, weil die falsche Ampel so aussah, als ob sie die Ampel für mich sei. Meiner Meinung nach muss das anders gemacht werden.

Rollenspielszenen: Sprengstoffspürhund

Rollenspielszene. Wir sind immer noch in einer besetzten Stadt und dringen gerade in ein Militärlager ein. Lilian, ein Teenager aus unserer Gruppe (Warum nehmen wir das Kind mit? Weil sie sonst ohne uns mitkommen würde.) hat den Sprengstoff, den Ariadne (eine Bastlerin) eigentlich beschlagnahmt hatte, entwendet um Bomben damit zu bauen und die auf die Mission mitzunehmen.

Wir haben uns zu nächtlicher Zeit erfolgreich in das Lager eingeschlichen (während überall in der Stadt Aufstände ausbrechen). Wir begegnen einem Hund, der sich gerade an einer Mülltonne vollfrisst. Als er uns bemerkt, schnüffelt er kurz und geht dann gezielt auf Lilian los. Alle versuche in abzulenken, scheitern zunächst, der Hund schnüffelt aufgeregt an Lilians Tasche, bevor er Alarm geben kann, wird er dann doch mit Essen abgelenkt.

Ariadne: „Lilian, was hast du da in deiner Tasche?“. Ein Blick in die Tasche bestätigt: Fünf Bomben, eine davon mit einer gefährlich kurzen Zündschnur. Ariadne lässt Lilian die Bomben, was soll man auch jetzt noch machen? Aber wir reden noch mal drüber! Und die mit der kurzen Zündschnur wird nicht benutzt!

Rollenspielszenen: Heilergildenmitgliedschaft

Rollenspielszene. Die Charaktere sind weiterhin auf der Suche nach einem speziellen Heilzauber. Die Niederlassung der Heilergilde in der Stadt Thelme könnte den Zauber haben. Mit 50% Rabatt für Mitglieder der Heildergilde. Außerdem haben sie vielleicht ein paar Betten frei. Auch nur für Mitglieder der Heilergilde.

Nini, Spielercharakter, Zi Ri, neigt dazu, Dinge zu vergessen. Als zie bei der Heilergilde vorspricht, wird zie nach zirer Mitgliedsmarke gefragt. Spieler würfelt. Eine 1. Kein Zimmer für die Nacht, und jetzt brauchen sie auch noch einen Bürgen, um den Zauber günstiger zu kriegen.

Hotelbuchungshorror

Ich muss demnächst noch einmal nach Hamburg, und möchte mir für vier Übernachtungen dort ein Hotelzimmer buchen. Wohlwissend, dass ich praktisch jedes Mal, wenn ich eine Hotelbuchungswebsite benutzen muss, einen Wutanfall bekomme weil das alles nicht funktioniert (Beispiel), und ich bei Plattformen wie booking dot com rot sehe, habe ich dieses Mal ein paar Leute in meiner Forma gefragt, ob sie mir Empfehlungen geben können.

Ich habe vier Hotelempfehlungen bekommen.

Erstes Hotel: Hat keine eigene Website, man kann wohl nur über Seiten wie booking dot com buchen. Fällt raus, den Scheiß mache ich nicht noch einmal mit.

Zweites Hotel: Ich kann ein Zimmer buchen. Ich muss es in Vorkasse bezahlen. Mit Debitkarte. Angeblich wurde die Zahlung von meiner Bank abgelehnt. Meine Bank hat dazu keine Informationen. Angeblich sind Online-Zahlungen mit der Karte freigeschaltet.

Drittes Hotel: Hier sind keine Zimmer mehr frei. Zehn Minuten vorher waren noch Zimmer frei. Aber es gibt Zimmer in der Nähe. Dieses Zimmer zum beispiel. Das ist aber belegt. Oder das Zimmer. Das ist auch frei. Aber schon belegt. Alle freien Zimmer in der Nähe waren es nicht.

Beim vierten Hotel lädt nicht einmal die Website. Die Verbindung wurde noch während des Ladens zurückgesetzt.

Und das ist nur die Kurzzusammenfassung, ohne die ganzen Mikroaggressionen, die mir diese Buchungswebsites über den Verlauf des Besuchs entgegenwerfen.

Dẹr Tag ̇ist im ̒Eiṁer. Ėig̒eṅtl̇i̇c̣h müss̒te ịcḣ ̇jetzt a̒uch ̒noc̣h Ḃạhntickets b̒uchėn, abẹr dafür ḟehl̒ṫ ̒mi̒r ḍėr N̒erv. Es kann doch ̜nic̔h͓t̔ s͓ein͘, das͓s i̜ch JE͘D̜E̔S ⃒MAL, WE⃓NN IC̵H⃓ E⃫IN H⃫O̷TELZ̵IMMER BU̸C⃦H⃒E, E̶I⃒NE̸N̶ N⃦E̷RVE⃦NZUSA̶M̵ME̶NBRUC̸H̶ K⃒R̶I̶EGE⃓!

Mausreparatur

Vor Jahren, in der Anfangszeit meines Studiums oder kurz davor, also vor 15 bis 17 Jahren wollte ich eine neue Maus für meinen Computer haben. Ich wollte eine ordentliche Maus, kein unbequemes Billigteil. Meine Überraschung war groß, als ich dann zu Weihnachten oder Geburtstag eine meiner Meinung nach völlig überteuerte Logitech-Gamermaus (G9) bekommen habe. Mit allen Kinkerlitzchen: Fünf (oder sechs, je nachdem wie man zählt) Tasten, über Schnelltasten verstellbare Empfindlichkeit, das Mausrad kann man zwischen normaler, stufenweiser und stufenloser Drehung umschalten (die stufenlose Variante war in Spore sehr praktisch, wo man oft sehr lange am Rad drehen muss um zunächst vom Planeten wegzuzoomen, dann aus dem Sonnensystem und dann noch ein bisschen, um Überblick über die stellare Nachbarschaft zu gewinnen. Von Wurmlöchern ganz zu schweigen), man kann sogar unterschiedliche Gewichte in der Maus platzieren, um sie auszubalancieren.

Sie war überteuert und hatte Features, die sich an Leute richteten, die meinten, damit besser spielen zu können. Aber sie hat gehalten. Über 15 Jahre lang. Bis sie vor ein paar Wochen einen Wackelkontakt am Kabelansatz bekam. Der wurde immer schlimmer, bis die Maus dann letzte Woche überhaupt nicht mehr lief.

Und hier kommt das Internet ins Spiel. Und zwar in der Form, in der ich es Anfang der 2000er-Jahre kennengelernt habe. Man sucht Informationen oder Anleitungen zu einem obskuren Thema (zum Beispiel wie man eine uralte Maus repariert) und findet tatsächlich etwas. In diesem Fall ein Video von jemandem, der genau das gleiche Problem repariert hat. In diesem Fall war das Problem zwar am Ende ein anderes, das Video zeigt aber trotzdem die vollständige Reparatur, mit allen Informationen, die ich brauchte.

Also habe ich mich an die Reparatur gemacht. Reparatur von Elektronik ist jetzt nichts, mit dem ich mich gut auskenne, aber die Anleitung war gut und es war ja nur ein Wackelkontakt, ein Kabelbruch oder so.

Eine schwarze Computermaus auf einer Korkunterlage. Die Maus hat mehr Tasten als üblich. Sie ist etwas dreckig und abgenutzt..

Hier kann man den Kabelbruch sehen. Ich habe noch ein Foto gemacht, auf dem er besser zu sehen war, aber meine Kamera hat sich im letzten Moment entschieden, lieber auf die Fläche hinter dem Kabel zu fokussieren, deswegen jetzt nur dieses Bild. an kann sehen, wie auch die Isolierung ab ist:

Nahaufnahme von einem schwarzen Mauskabel, gehalten von mehreren Fingern. In der Mitte ist die Isolierung des Kabels aufgebrochen.

Ich gehe jetzt nicht im Detail die Reparatur durch, das ist in dem verlinkten Video sehr gut erklärt. Ich habe die Maus auseinandergenommen, eine Woche Pause eingelegt, bis ich an Schrumpfschlauch gekommen bin, habe das Kabel zusamengelöten und den Schrumpfschlauch geschrumpft. Das einzig Schwierige war, die Maus hinterher wieder zusammenzuschrauben. Das Kabel war ein bisschen weiter im Gehäuse drin, und drinnen war nur wenig Platz (die beweglichen Teile wie das Mausrad und die Tasten müssen ja weiterhin beweglich sein). Ich habe es aber am Ende geschafft, das Kabel zu verlegen und auch den Deckel mit sanfter Gewalt wieder zusammenzufügen.

Die untere Hälfte einer aufgeschraubten Maus. Man kann die Leiterplatte sehen, das Mausrad, Taster für die Maustasten und insbesondere ein Kabelbündel, das vom vorderen Ende der Maus auf der rechten Seite der Maus nach hinten durchgeführt wird und dort eine kleine Schleife macht bevor es ein Stückchen weiter vorne in einem Steckkontakt steckt.

Jetzt funktioniert die Maus wieder, und es fühlt sich toll an dieses alte Gerät gerettet zu haben. Diese Maus hat mich über Jahre begleitet (ich glaube, es waren wirklich eher 17 als 15), und es wäre schade gewesen, sie nur wegen eines Kabelbruches wegzuwerfen.

Besonderen Dank noch einmal an den Ersteller des Reparaturvideos. Das Video ist angemessen kurz, beinhaltet alle Informationen, ist ruhig und sachlich vorgetragen, man kann die Schritte 1:1 nachvollziehen und an der eigenen Maus wiederholen. 10/10 Punkte. Für solche Sachen ist das Internet da.

Rollenspielszenen: Kopfkino

Rollenspielszene. Wir schleichen weiter durch eine Militärbasis. Dabei haben wir einen Geisterhund (eher ein Ætherhund, aber man will ja nicht so kleinlich sein). Der Geisterhund kann, muss aber nicht mit Materie interagieren. Kann also durch Wände gehen aber trotzdem Dinge apportieren.

Während der letzten Runde waren wir ein einem Paar vorbeigekommen, die sich nackt in einem aufblasbaren Pool vergnügten, in der Hoffnung, dass der Vorgesetzte nichts davon mitkriegt.

Wir brauchen eine Schlüsselkarte. Dr. March schickt den Hund los. Ein kurze Zeit später hören wir empörtes Geschrei aus einem anderen Teil des Lagers. Spielleiter:

Der Hund kommt ein paar Minuten später zurück. Er trägt einige Sachen. Eine davon ist ein Fetzen eines Swimmingpools.

Rollenspielszene: Schlechter erster Eindruck

Rollenspielszene. Unsere Gruppe war auf einer langen Forschungsexpedition auf einem halb untergegangenen Kontinent. Gefährliche magische Effekte. Unberechenbare Öffnungen zu anderen Ebenen. Untote Elementarwesen. Und zuletzt (durch Wirken unseres zunehmend erratischer handelnden, rassistischen Magiers) ein Abstecher in die Feenwelten.

Die ganze Rückreise hatten wir die Wilde Jagd im Nacken. Jetzt, endlich, ein Hafen in Sicht. Die Hafenautoritäten schicken ein Boot zur Inspektion herüber. Die Kapitänin des Schiffes und der Paladin, der die Expedition angeführt hat, stehen an Deck und empfangen sie.

Währenddessen, unter Deck: Unser Rogue, ein Grung, hat dem Magier ein gefährliches verzaubertes Schwert geklaut. Der Magier hatte es aus den Feenwelten mitgehen lassen. Aufgrund des wiederholten Verrats durch den Magier und dessen größenwahnsinnige Allüren meinte der Rogue, dass der Magier kein göttertötendes Schwert besitzen sollte. Der Magier war anderer Meinung.

Da sich der Magier nicht in der Lage sah, den Grung im Laderaum zu finden, begann er, explosive Flächenzauber zu wirken.

Oben an Deck: die Hafenbeamten betreten gerade das Schiff. Eine Explosion im Schiffsrumpf. Der Paladin entschuldigt sich und geht eilig nachschauen. Die Waldläuferin rennt panisch unter Deck, ruft den Beamten etwas von „das war nur die Schiffskatze“ zu.

Eine zweite, größere Explosion. Waldläuferin: „Das sind nur die explosiven Ratten, die wir an Bord haben!“. Paladin sieht das Feuer, ruft die Druidin um Hilfe. Grung knockt den Magier aus. Feuer kann gelöscht werden.

Die Hafenautoritäten waren nicht amüsiert und haben uns alle direkt festgenommen. Schöner erster Eindruck, den wir da geliefert haben.

Rollenspielszenen: Da ist etwas im Wasser!

Rollenspielszene: Die Helden haben jetzt eine Heilerin und einen Heilzauber für eine gefährliche Krankheit. Sie haben den ganzen Tag gebraucht, um alles zu organisieren, und jetzt fahren sie in der Nacht zurück über den See nach Hause.

Alle schlafen, nur die Steuerfrau des Bootes (Fizzle) und das junge Zi Ri, Nini, sind noch wach. Plötzlich sieht Nini einen Schatten im Wasser! Aufgeregt zischt Nini von Reling zu Reling und versucht, Genaueres zu erkennen, aber es ist zu dunkel. Fizzle tut alle ihre Hinweise ab. „Nein, da ist nichts im Wasser, du bildest dir das nur ein“.

Nini weckt ihren Mitreisenden, den Orren Sprinkle auf. Der kann im Dunkeln sehen. Noch etwas verschlafen blinzelt er. (Spieler würfelt. Würfel explodiert. Eine 35 auf einem 20-seitigen Würfel).

Sprinkle ist sofort hellwach. Denn was er sieht, in allen Details, ist ein riesiger Fisch, der mit aufgerissenem Maul auf das Boot zuschwimmt.

Unicode-Vortrag auf der FrOSCon

Die letzten Tage über wurde ich via Mastodon auf einige Vorträge der diesjährigen FrOSCon aufmerksam. Darunter auch der Vortrag „Unicode für Anfänger“.

Ich betrachte mich nicht als Anfänger, was Unicode angeht, aber ich habe mir den Vortrag trotzdem angeschaut. Zum Einen, damit ich weiß, ob ich ihn weiterempfehlen kann (kann ich). Zum Anderen, weil ich immer gerne mal wieder daran erinnert werde, welche ungeahnten Probleme es mit Schriften, Sprachen und Texten gibt, an die man üblicherweise nicht denkt. Und zuletzt, weil ich ja vielleicht doch noch etwas Neues lernen kann.

Und das habe ich. So habe ich zum Beispiel gelernt, dass es getrennte Code Points für das groe Omega (U+03A9, GREEK CAPITAL LETTER OMEGA, Ω) und das Zeichen für die Maßeinheit für elektrischen Widerstand, Ohm (U+2126, OHM SIGN, Ω) gibt. Nebeneinander: „ΩΩ“. Interessant auch: Nach jeder im Standard definierten Normalisierung wird das Ohm-Zeichen zu einem großen Omega normalisiert. Hat mich ein bisschen an die römischen Zahlen in Unicode erinnert.

Überhaupt legte der Vortrag einen gewissen Fokus auf Normalisierung, Homoglyphen/Homographen und alphabetische Sortierung, und Andeutungen auf deren Sicherheitsrelevanz. Weit in die Tiefe ging der Vortrag allerdings nicht, sollte aber ausreichen, damit man sich bewusst wird, dass alles schwieriger ist, als man auf Anhieb denkt.

Der Vortragende ist selbst kein Unicode-Experte und musste sich dieses Wissen nur notgedrungen aneignen (eine verwandte Seele!). Ein paar kleine Korrekturen habe ich auch (der Autor meinte, er habe immer gesagt bekommen: „Wenn du dir bei einem Thema nicht 100% sicher bist, schreib's im Internet, irgendeiner wird dich korrigieren“).

Zum Einen: Obwohl er die Uneinheitlichkeit der lexikographischen Sortierung als schwierig darstellt, behauptet er, dass es im Deutschen eine Sortierung gibt. Es gibt aber allein in der deutschen Sprache mindestens zwei offizielle Standards, und einer davon, der DIN 5007-Standard kennt zwei Varianten. Es ist also, selbst wenn man die Sprache kennt, nicht eindeutig.

Zum Anderen sagt er, dass Python UTF-32 verwendet, wenn mindestens ein nicht-ASCII-Zeichen im String vorkommt, sonst ASCII. Das ist nicht ganz korrekt. Zwischen diesen Extremen gibt es nämlich noch eine 16-Bit-Codierung, wenn alle vorkommenden Code points in 16 Bit codiert werden können. Ich hatte das vor Jahren mal für einen kleinen Vortrag recherchiert und diesen Blogpost dazu gefunden.

Immerhin haut der Vortrag zu Recht auf UTF-16 drauf: „Es hätte eigentlich deprecated gehört“. Nur die Einschätzung, dass UTF-16 kaum noch verwendet wird, kann ich nicht teilen. Zugegeben, als Transportencoding sieht man es selten (mir ist ein Mal eine UTF-16-codierte XML-Datei untergekommen, die hatte kein BOM und unser Decoder hat sie direkt falsch geparsed), aber an vielen Stellen ist es als internes Encoding noch weite Verbreitet. Der Vortrag nennt nur Windows und Javascript, aber auch Java und C# haben UTF-16 als Stringencoding (fun fact: keines der vier Beispiele behandelt UTF-16 korrekt).

Genug des Erbsenzählens. Das ist ein guter Einsteigervortrag zu Unicode. Schaut ihn euch an.

Not an LLM

Ich hatte ja in meinem großen Artikel über die Probleme mit LLMs schon erwähnt, dass Daniel Stenberg, der curl-Typ, Probleme mit Leuten hat, die vorgeben (oder sogar wirklich glauben), mit Hilfe eines LLM Sicherheitslücken in curl gefunden zu haben und damit Stunden Zeit von curl-Entwicklern klauen, die das verifizieren wollen und feststellen müssen, dass es alles Müll ist. Stenberg hat eine Liste von Fällen.

Auf der FrOSCon hat er jetzt einen Vortrag über die curls Probleme mit AI-Slop gehalten. Wer also hören möchte, was genau das Problem ist, dem kann ich diesen Vortrag empfehlen.

Ich selber schreibe in diesem Blog noch alles von Hand. Bis auf Stellen, wo ich es explizit angebe, z.B. in diesem Artikel über meine ersten Experimente mit ChatGPT. Parallel dazu habe ich, bei der typografischen Auffrischung alter Blogposts, einige Änderungen vorgenommen. Zum Beispiel habe ich drei Punkte (...) durch typografisch korrekte Auslassungspunkte (…) ersetzt. Und eine Menge ASCII-Bindestriche/Minuszeichen (-) durch den Halbgeviertstrich (–), im Englischen auch „en dash“ genannt. Der wird im Deutschen als Gedankenstrich verwendet, im Englischen ist der Geviertstrich (—, „em dash“ in Englisch) verwendet. Die meisten Leute kümmern sich nicht dadrum und nehmen einfach das ASCII-Zeichen. Und genau da liegt das Problem.

In dem Vortrag stellt Stenberg auch typische Merkmale von LLM-generiertem Text vor. Darunter: die Benutzung von Geviertstrichen: „it's sort of complicated to add an em dash into text“. Und er ist nicht der Einzige, ich treffe im Internet immer wieder auf Listen mit solchen Merkmalen.

Nun ist es so, dass ich es, danke compose key ziemlich einfach habe, viele solcher Sonderzeichen einzufügen. Ein Halbgeviertstrich ist compose key + ..-. Ein Geviertstrich compose key + --- und Auslassungspunkte compose key + ... Wenn man das einmal drin hat und so besessen ist wie ich, dann geht das leicht von der Hand.

Vielleicht sollte ich auch so Disclaimer wie Randall Munroe hinzufügen. Auf der anderen Seite: Bei meiner Tippfehlerdichte werden schon alle Leute glauben, dass ich wirklich ein Mensch bin.

dotnet fucking format

Code-Style-Regeln sind an sich ja eine nette Sache. Wenn man gute Regeln hat und die einhält, ist der Code überall einheitlich, einfach zu lesen und an findet sich schnell zurecht.

Das Einhalten von Regeln ist natürlich immer so eine Sache, und wer möchte schon mühsam Zeilen umbrechen und einrücken und nachschauen, dass alle Leerzeichen richtig gesetzt sind, wenn man eigentlich an der Software arbeiten möchte. Deswegen gibt es Code-Formatter. Das sind Programme, die diese langweilige Arbeit übernehmen und den Programmierern die Zeit geben, sich auf das eigentliche Problem zu konzentrieren.

Der klassische Ansatz von Code-Formattern ist, dass man denen einen Haufen von Regeln vorgibt, und die danach den Code formatieren. Das stammt noch aus der Zeit bevor es Code-Formatter gab und sich ein ganzer Haufen unterschiedlicher Code-Styles für zum Beispiel C entwickelt hat, jeder brauchte also etwas Anderes.

Moderne Sprachen ohne solchen Ballast haben mehr oder weniger von Anfang an ihren eigenen Code-Formatter, der meist ein ordentliches Regelwerk hat und wenig bis überhaupt nicht konfigurierbar ist. gofmt für Go war der erste dieser Art, der mir untergekommen ist, dicht gefolgt von rustfmt für rust.

Keine dieser Sprachen ist eine Sprache, mit der ich beruflich gerade arbeiten kann. Stattdessen muss ich C# benutzen. Und C# hat dotnet format. Es gibt noch andere Formatter, aber das ist der offizielle, der Standard. Und er ist Kacke.

Zum Einen ist er unglaublich langsam. Das ist mir schon bei den Vorbereitungen zum Vergleichsoperator-Blogpost aufgefallen. Zum Anderen ist er nicht idempotent: Unter bestimmten Bedingungen muss man ihn mehr als ein Mal laufen lassen, damit er alles macht, was er machen will. Oh, und er fügt in solchen Situationen gerne ohne Warnung schlecht geschriebenen Code hinzu, der wild mit Exceptions um sich wirft.

Das alleine ist schon doof genug. Aber dotnet format kann keine Zeilen umbrechen. Wenn man also einen Funktionsaufruf oder eine Funktionsdefinition mir vielen oder langen Parametern hat, wird dotnet format die nicht in je eine eigene Zeile verschieben. Ketten von Funktionsaufrufen, wie sie bei Iteratoren vorkommen, werden auch nicht umgebrochen. Andere Formatter haben Angst davor, Zeilenumbrücke wegzunehmen. dotnet format fügt aber auch keine hinzu, auf wenn sie wirklich, wirklich einfach und wirklich, wirklich nützlich wären.

Dazu kommt dann, dass, wenn man in solchen Situationen dann manuell umbricht, sich dotnet format auch weigert, diese umgebrochenen Zeilen korrekt einzurücken. Man muss also für zwei der Hauptfälle, für die man einen Code-Formatter hat, manuell formatieren. Wer macht so einen Mist?

Ach ja. Microsoft natürlich.

Rollenspielszenen: Wir wollen jemanden töten.

Rollenspielszene. Beim Einbruch ins Militärlager haben wir schlussendlich die zehnjährige Tochter der feindlichen Generälin entführt, weil dieses Kind briliant ist und Massenvernichtungs-Ætherwaffen entwirft.

Diese Entführung war innerhalb der Gruppe sehr umstritten. Ariadne war im Moment der Entführung nicht ganz bei sich und realisiert erst am nächsten Morgen, was sie getan haben. Das Ziel ist klar: Das Kind muss sicher zurückgebracht werden!

Aber wie lenkt man Dr. Erika Sjöstroem ab, die das Kind zwar nicht verletzen, aber auch nicht wieder freilassen will? Ariadne findet Hilfe bei Lilian und ihrer besten Freundin. Die beiden haben in der Nacht bei Aufständen mitgemacht, ein Gewehr ergattert und haben jetzt die fixe Idee, jemanden umbringen zu müssen. Sie gehen zu Erika:

Hey, wir wollen jemanden töten. Wen können wir töten?

Erika hat es geschafft, sie davon abzubringen.

ImageMagick

Neulich habe ich einen Vortrag zu meinem digitalen Fordit gehalten. Als Folien hatte ich praktisch nur Bilder, also habe ich weder LaTeX noch andere Programme genommen, die man üblicherweise für Präsentationen nutzt, sondern einfach einen Haufen Bilddateien vorgeführt.

Dazu musste dann einige Bilder noch irgendwie verwursten. Zum Beispiel einen Haufen von Höhenkarten zu einem Bild zusammenfügen, so dass man sie nebeneinander sehen kann. Oder Bildunterschriften (CC-Lizenzhinweise) in die Bilder einfügen. Natürlich kann man das auch mit Bildverarbeitungsprogrammen wie Gimp machen. Aber gerade für das Zusammenfügen von Bildern wäre das sehr fummelig geworden, und ich habe ich zwischendurch auch ein paar Mal umentschieden, welche Bilder drin sind und welche nicht.

Also wäre ein einfaches Tool praktisch, mit dem man das ganz einfach über die Kommandozeile machen kann. Und das gibt es natürlich: ImageMagick Ein Schweizer Taschenmesser für Bildbearbeitung. Bisher habe ich das meist nur zum Skalieren von Bildern verwendet. Aber es hat viele Funktionen.

Text in ein Bild einfügen mit ImageMagick

Mit ImageMagick Text in ein Bild einzufügen ist relativ umständlich, weil es sehr viele Optionen gibt. Ich wollte einfach einen Text, der das Bild unten überlagert. Das habe ich mit folgendem Befehl hingekriegt:

magick input.jpeg -font "Noto-Serif-CJK-SC" -background black -fill white -pointsize 72 -gravity South -annotate +0+2 "something copyright" output.jpeg

Damit wird die Datei input.jpeg genommen und in der Schriftart Noto-Serif-CJK-SC (Option -font) in weißer Schrift (Optionn -fill white) und Schriftgröße 72 (-pointsize 72) unten in der Mitte des Bilders (-gravity South) der Text something copyright eingefügt und das Ergebnis in output.jpeg gespeichert. Fragt mich nicht, was das -annotate +0+2 bedeutet, aber ich weiß noch, dass es wichtig war.

Wahrscheinlich wäre ein Bildbearbeitungsprogramm hier einfacher gewesen. Aber es ist trotzdem nützlich, wenn man viele Dateien mit Texten versehen möchte, oder so etwas automatisch machen muss.

Die Schriftart habe ich übrigens ausgewählt, weil eines der Bilder von einer Person namens 峠 武宏 unter eine CC-Lizenz gestellt wurde, und die Standardschriftart diese Schriftzeichen nicht enthält. Anstelle von Platzhaltern würde ImageMagick hier überhaupt nichts anzeigen. Also bei automatischer Verarbeitung vorsichtig sein!

Bilder zusammenfügen

Bilder zusammenfügen geht viel einfacher:

montage -define webp:lossless=true -background darkgreen in_1.webp in_2.webp in_3.webp in_4.webp out.webp

Damit werden alle in_?.webp-Dateien zusammengefügt, mit jeweils ein bisschen Abstand zu allen Seiten. Dieser Abstand ist in diesem Fall dunkelgrün (um ihn von den schwarzweiß-Höhenkarten abzuheben, die in den Bildern enthalten sind). Das Ergebnis wird (verlustfrei komprimiert dank -define webp:lossless=true) in out.webp gespeichert.

Wichtig ist hier, dass ImageMagick die Bilder ab einer bestimmten Größe runterskaliert. Das kann man aber mit der -geometry-Option verändern, so kann man zum Beispiel das Skalieren mit -geometry +2+2 abstellen (das +2+2 sorgt dafür, dass immer noch ein Abstand zwischen den Bildern gehalten wird, +0+0 würde bedeuten, dass es keinen Abstand gibt).

Security

Eines der schönen Dinge an Imagemagick ist, dass es sich gut zur Automatisierung eignet und einen Riesenhaufen an Bildformaten unterstützt.

Das Gefährliche an ImageMagick ist, dass es zur Automatisierung sehr weit verbreitet ist und einen Riesenhaufen an (teilweise sehr exotischen) Bildformaten unterstützt.

Fangen wir mit dem zweiten Punkt an. Parser für komplexe Dateiformate zu schreiben ist schwierig. Und alle gängigen Dateiformate sind komplex. Nur als Beispiel: ein Kollege von mir musste beruflich einmal Bilder eines Formats (Tiff, glaube ich) parsen und in ein anderes Format umwandeln. Die Idee war nicht das ganze (möglicherweise ziemlich große) Bild in den Speicher zu laden, sondern die Daten zu streamen. Stellte sich als schwierig heraus, weil das Eingangsbildformat seinen Header nicht am Anfang hatte. Also zumindest nicht immer und nicht den ganzen Header. Manchmal waren Teile davon (wie die Bilddimension) auf irgendwelche Sub-Header verteilt, die irgendwo in der Bildatei liegen konnten.

Komplexität bedeutet, dass mehr Code geschrieben werden muss und es schwieriger ist, den Code zu verstehen. Beides ist guter Nährboden für Bugs und damit für Sicherheitslücken. Bild- Video- und Audioformate sind dafür notorisch. Und ImageMagick ist in C geschrieben. Jeder Speicherfehler (z.B. weil man sich auf Größenangaben aus der Datei verlässt) ist potentiell eine Code-Execution. Das will man nicht.

Dazu kommt der erste Punkt: ImageMagick ist weit verbreitet. Viele Websites nutzen es, um im Hintergrund hochgeladene Bilder zu verarbeiten (z.B. um Thumbnails zu erstellen). Das bietet viel Angriffspotential.

Jetzt könnte man sagen: „Ist ja in Ordnung, aber ich lasse ja nur GIF- PNG- , JPEG- und WEBP-Bilder zu, und die Decoder dafür sollten ja gut genug überprüft sein. Exotische Bildformate mit schlecht getesteten Parsern brauche ich nicht.

Schön und gut, nur funktioniert ImageMagick in der Standardeinstellung nicht so. Dateinamen sind Schall und Rauch, und das gilt insbesondere auch für die Dateiendungen. Die sind nicht mehr als ein lieb gemeinter Hinweis, was in der Datei sein könnte. Eine Datei foo.webp könnte also in Wirklichkeit eine JPEG-Datei sein. Oder irgendetwas, von dem wir noch nie gehört haben. ImageMagick versucht, das Format automatisch zu erkennen.

Automatische Erkennung ist aber schwierig. Insbesondere gibt es Künstler/Hacker, die sich einen Spaß daraus machen Dateien zu konstruieren, die mehrere gültige Dateiformate gleichzeitig sind. Das war vor zehn Jahren, der Typ ist immer noch aktiv. Es ist also schwierig hervorzusagen, mit welchem Decoder ImageMagick die Datei öffnen wird.

Man kann das Problem einschränken, indem man ImageMagick dazu zwingt, sich auf ein Format festzulegen, z.B. indem man den Namen der Inputdatei mit einem <format>:-Prefix versieht:

convert webp:in.webp -scale 50% out.webp

Wenn in.webp jetzt in wirklichkeit eine JPEG-Datei ist, kriege ich den folgenden Fehler:

convert: corrupt image `in.webp' @ error/webp.c/ReadWEBPImage/563.

(DISCLAIMER: es gibt vermutlich noch einen ganzen Haufen anderer Dinge, auf die man achten muss. Das hier ist nur ein Beispiel und soll keine Anleitung sein, wie man ImageMagick sicher benutzt).

Es werden auch heute noch gelegentlich Sicherheitslücken in ImageMagick gefunden. Also, was tun? Man kann Alternativen nehmen. Die können aber auch Sicherheitslücken haben. Oder bieten nicht die Funtkionen, die man braucht. ImageMagick immer auf dem aktuellen Stand (Sicherheitspatches!) zu halten, hilft sicher. Vielleicht das Tool nur in einer Sandbox ausführen, so dass code execution bugs keine Chance haben, viel Schaden anzurichten? Nur Bilder aus vertrauenswürdigen Quellen verarbeiten?

Auf jeden Fall: Vorsichtig sein. Schauen, was andere empfehlen. Und das gilt nicht nur für ImageMagick sondern auch für alle anderen tools, die unglaublich praktisch sind und mit einem riesigen Haufen komplexer Dateiformate umgehen können.

Trotz allen Sicherheitsbedenken ist ImageMagick eine tolle Sammlung von Werkzeugen. Mir hat es schonoft geholfen.