Archive for August, 2007

Netzneutralität

Mittwoch, August 15th, 2007

Ich habe gerade mal wieder auf Heise etwas zum Thema Netzneutralität gelesen. Die Gegner der Netzneutralität führen nun ins Feld, dass z.B. eine Krankenakte bevorzugt behandelt werden müsse.

Setzen wir ein wenig tiefer an: Wann ist es notwendig ein Nachrichten-Packet im Netzwerk zu bevorzugen? In dem Moment, in dem die Leitungskapazität nicht für alle Packete reicht.

Dann gibt es verschiedene Möglichkeiten:

  1. Packete verwerfen bis der Rest durch die Leitung passt
  2. einige Packete durch eine langsamere Route schicken
  3. einige Packete durch eine teurere Route schicken
  4. Packete zurück stellen

Ad 4.: Dieser Punkt kann aus technischer Sicht nur sehr begrenzt angewendet werden, da ein flotter Speicher in der passenden Größenordnung verdammt teuer ist.
Ad 2.: Dies tut der Krankenakte nicht weh. Selbst bei einer online-OP wird der Arzt einen Lag von einigen Millisekunden nicht merken.

Ad 3.: Das tut dem Netzbetreiber im Geldbeutel weh. Diese wollen wahrscheinlich lieber den 1. Punkt anwenden und gehen daher auf die Barrieren.

Ad 1.: Ein TCP-Packet wird dann erneut gesendet. Ein udp-Packet ist einfach verloren. Bei ausreichend dimensionierten Netzen (wie sie im Moment größtenteils vorhanden sind), ist das aber nicht nötig.

Eine Aufgabe der Netzneutralität hat für den Netzbetreiber also drei Handfeste Vorteile:

  1. Er muss die teuren Routen nicht mehr so häufig in Anspruch nehmen.
  2. Er kann seine Netze knapper dimensionieren.
  3. Er kann für Priorisierung extra Geld nehmen.

Ich prophezeie daher folgende Entwicklung: Die unpriorisierten Internet-Kosten werden sich wie bisher entwickeln, das Netz dafür im Durchschnitt einen höheren Lag und mehr Packetverluste aufweisen. Priorisierter Verkehr wird dadurch für die, die es brauchen notwendiger und natürlich teurer. Nach und nach werden sich andere Nutzer für den priorisierten Verkehr entscheiden (YouTube, Skype, Gamer etc). Je mehr sich für den priorisierten Verkehr entscheiden, desto schlechter wird das unpriorisierte Netzwerk bis irgendwann auch die normalen Surfer lieber „priorisiert“ Surfen. Am Ende sind wir wieder da, wo wir auch am Anfang waren: Alle Netzteilnehmer haben gleiche Priorität und (wieder) ein zuverlässiges Internet, nur die Netzbetreiber nehmen für diese Priorisierung mehr Geld.

Wärmedämmung im Häusle-Bau

Dienstag, August 7th, 2007

Es erscheint jedem Menschen auf Anhieb als richtig, wenn jemand sagt, dass ein Haus ordentlich eingepackt werden muss, damit die Wärme nicht flöten geht. Das ist aber viel zu kurz gesprungen. Es gibt noch so viele weitere Effekte, die beachtet werden müssen:

  • Warme Wände sind wichtiger als warme Luft für ein kuscheliges Klima.
  • Warme Luft kondensiert an kalten Wänden und Gegenständen. An den feuchten Stellen kann es dann Schimmeln.
  • Massive Wände speichern sehr viel Wärmeenergie. Dies entspricht einen Kondensator, der große Temperaturschwankungen abfängt.
  • Die Sonne erwärmt ein Haus von außen meist mehr, als dieses Wärme-Energie abgibt.
  • Top isolierte Fenster verhindern den Luftaustausch.
  • Einfach-Verglasung kann als Soll-Kondensationsfläche benutzt werden.

Konrad Fischer berichtet teils unterhaltsam polemisch aus der Welt der Gebäudetemperierung und fällt über die heutzutage übliche Konvektions- und Fussbodenheizungen sowie Gebäudedämmung her. Es sei vorher gewarnt: Er ist kein Layout-Künstler. Und seinem gesunden Menschenverstand traut er vernünftigerweise mehr als einer Meßkurve.
http://www.konrad-fischer-info.de/

ReMastering Regular Expressions

Dienstag, August 7th, 2007

Let’s have a look at the source of the perl module Email::Valid and search for „Mastering Regular Expressions“. You will find Jeffrey Friedl’s regex, which matches all valid email adresses – and nothing more. It seems so complicated, that no one could validate it by just looking at the regex. I will show you, how to disenchant it.

The disenchanting is based on the following rule:
Let us have $a=qr/foobar/, $b=qr/foo/, $c=qr/bar/ and $d=qr/$b$c/. $string=~$d behaves exactly as $string=~$a.

Now open Jeffrey Friedl’s regex in an editor of your choice and start to replace some strings. Be careful to replace them literally „15“ means \ and 0 and 1 and 5 instead of „\r“ or chr(0) or whatever.

Search for

Replace with

Count

\\\x80-\xff\n15 $c 128
[^(40)@,;:“.\\\[\]00-37\x80-\xff] $d 26
\\[^\x80-\xff] $e 68
\([^$c()]*(?:(?:$e|\([^$c()]*(?:$e[^$c()]*)*\))[^$c()]*)*\) $f 27
[40\t]*(?:$f[40\t]*)* $g 26
„[^$c“]*(?:$e[^$c“]*)*“ $h 6
\[(?:[^$c\[\]]|$e)*\] $k 8
[^()@,;:“.\\\[\]\x80-\xff00-1012-37] $m 2
(?:$d+(?!$d)|$h) $n 5
$g(?:$d+(?!$d)|$k)$g $o 8
@$o(?:\.$o)* $p 4
$n$g(?:\.$g$n$g)*$p $q 2
$g(?:$q|$n$m*(?:(?:$f|$h)$m*)*) $s 1

After this replace-marathon your editor should show only „$s“.
The original regex contains 6599 characters. If you save the content of the variables this way:

$p = qr/\@$o(?:\.$o)*/;

you will end with $s containing 8129 characters of which are around 900 qr//-overhead (as „-xism“) and a script with total size of 514 bytes for exactly the same thing.
Those, who have already greater experience with regular expression, should have already seen the possibilities to optimize most of the regexes in size. I will show my optimizations. But the main goal is already reached: You have a small set of small regular expressions. And each small expression is understandable for itself.

Optimized Expression

my $c = ‚[:^ascii:]\\n\\r\\\\‘;
my $d = qr([\w!#\$%&’*+-/=?^`{|}~\x7F]);
my $e = qr/\\[[:ascii:]]/;
my $g = qr/(?:$f|[\x20\t])*/;
my $h = qr/\“(?:$e|[^$c\“])*\“/;
my $k = =qr/\[(?:$e|[^$c\[\]])*\]/
my $f = qr/\((?:$e|[^$c()]|\((?:$e|[^$c()])*\))*\)/;
my $m = qr/$d|[\x20\t]/;
my $n = qr/$d+(?!$d)|$h/;
my $o = qr/$g(?:$d+(?!$d)|$k)$g/;
my $p = qr/\@$o(?:\.$o)*/;
my $q = qr/$n$g(?:\.$g$n$g)*$p/;
my $s = qr/$g$q|$g$n(?:$f|$h|$m)*/;

There are of course more optimizations possible – try it yourself. The length of my $s is 5144 („-xism“s deleted). The code uses 457 bytes without comments. (Remember: We originally dealt with 6599 characters pure regex.)

Of course I was supported by a little script. Feel free to ask me, if you are interested.

Unicode mit Perl

Dienstag, August 7th, 2007

Unicode unter Perl funktioniert meistens einfach. Über das warum und wieso muss man sich meistens keine sorgen machen. Wenn man denn trotzdem mit Zeichensätzen spielen möchte, so muss man hinter die Kulissen blicken.

Ausgangssituation

Zuerst einmal die Ausgangssituation: Meine mp3-Sammlung. Sie hat im Laufe ihres Lebens diverse male ihr Speichermedium gewechselt und ist weiter gewachsen. Bei jedem Kopiervorgang einer Datei wird eine neue Datei mit dem gleichen Dateinamen und dem gleichen Inhalt angelegt. Bei den Dateinamen fangen die Probleme an. Was bedeutet „gleich“. Heutzutage werden auf jedem vernünftigen Betriebssystem die Dateinamen als UTF gespeichert (meistens UTF-8). Jedoch sind auch Zeichensätze der iso-8859 (iso-8859-1 oder iso-8859-15 im europäischen Raum) oder gar Codepages (wie cp1250, cp850, cp437) auf Windows-Systemen im Einsatz.

ASCII

Das ist alles kein Problem, solange sich alle Zeichen eines Dateinamens im ASCII-Zeichensatz befinden. Der ASCII-Zeichensatz wurde von Amerikanern erfunden, die der Meinung waren, dass die ganze Welt nur die Zeichen A-Z, a-z, 0-9, Sonderzeichen wie !“$&\|[](){}=*+-/%~#’_.:,?!; (nicht vollständig) und verschiedene Leer- und Steuerzeichen gebraucht. Es wurde jedoch bald erkannt, dass diese 128 verschiedenen Zeichen (\x00-\x7F) nicht der Weisheit letzter Schluss sind. Also entstanden genau so kurzsichtig diverse Definitionen, die den übrigen 128 Zuständen eines Bytes (\x80-\xFF) ein Bildchen verpassten. Somit waren die ASCII-Erweiterungen (iso-8859-1 bis iso-8859-15 und einige Codepages) geboren. Am Beispiel einer Tabelle einiger Zeichensätze auf Wikipedia werde ich mein Problem verdeutlichen.

Kopieren

Ich habe es wie auch immer geschafft, eine Datei mit dem Zeichen ´ (\xB4) auszustatten. Das ist der Akzent, der aus einem Cafe einen Café macht. Jedenfalls hieß die Datei dann „Salt´n´Pepper – Push It.mp3“. Abgesehen davon, dass die Band falsche geschrieben ist (Salt-N-Pepa), sind da nun noch zwei nicht-ASCII-Zeichen versteckt. Es ergab sich, dass dieser Dateiname in der Windows Codepage 1252 (oder 1250? – ich weiß es nicht mehr) gespeichert wurde. Die Festplatte unter Linux angesprochen hat die Bytekette, die den Dateinamen repräsentiert nun aber als iso-8859-15 interpretiert, und daher für das Zeichen Ž (\x017D) gehalten. Das ganze dann als UTF-8 neu abgespeichert ergibt „SaltŽnŽPepper – Push It.mp3“.

Fast jede Datei hat so ihre Geschichte. Die meisten bestehen zum Glück nur aus ASCII-zeichen. Und viele sind einfach UTF-8 interpretierte, aber iso-8859-15 kodierte Dateinamen. Ich wollte diese jetzt alle korrekt nach UTF-8 konvertieren, da mir dieser Zeichensatz zukunftssicher erscheint.

Repräsentation in Perl

Perl speichert Strings in Scalaren (z.B. $file). Ein Scalar enthält Zeichen und einen Perl-internen Overhead der diverse Flags und die Länge enthält. Damit hat man aber eigentlich nichts am Hut. Seit Perl Version 5.6 wird für jedes Zeichen eines Scalares ein Wide-Character (2 Bytes) benutzt. Vorher galt ein Byte pro Zeichen. Erstmal ändert sich dadurch nichts. Ein UTF-8-kodierter String (z.B. aus einer Datei, einem UTF-8 kodierten Perl-Script oder dem Terminal als Argument) wird nach wie vor in einem Haufen von Zeichen mit einem dezimalen Wert von 0-244 gespeichert. (Die Kombinationen \xF5-\xFF, sowie \xC0 und \xC1 kommen in gültigen UTF-8 Sequenzen nicht vor.) Wenn er wieder geschrieben wird, so bleibt er UTF-8 kodiert. Ein m/ü/ in einem script (UTF-8) ist das gleiche wie m/\xC3\xBC/ (ü = \xFC (iso-8859-1) = \xC3\xBC (UTF-8)). Das ist schlecht, wenn Script und Daten in verschiedenen Zeichensätzen kodiert sind.

Nun gibt es aber für jeden $scalar ein UTF8-Flag. Perl merkt sich damit, ob es in den Wide-Characters des $scalars direkt den code point gespeichert hat anstatt nur die kodierte Form. Der code point ist eine eindeutige Zahl, die von der ISO-10646 jedem Zeichen zugeordnet ist – für ASCII-Zeichen ist er äquivalent.

Umwandlung in Perl

Wie bekommt man nun Perl dazu, den Inhalt eines $scalars als Zeichen zu interpretieren und in Codepoints zu dekodieren?

  • use utf8; $scalar=“äöü“; wenn der Inhalt von $scalar im script steht.
  • binmode(FILEHANDLE, „:utf8“); $scalar=; wenn der Inhalt von $scalar aus einem file handle kommt.
  • use Encode; $scalar2=decode(„utf8“,$scalar1); falls $scalar1 bereits UTF-8 kodierten Inhalt enthält.

Das Flag lässt sich mit $utf_encoded = Encode::is_utf8($scalar); abfragen. Anstatt „utf8“ kann man auch „iso-8859-1“ oder ähnliches verwenden. Ich bin so faul und erlaube mir für weitere Informationen auf die Dokumentation von Encode, binmode, utf8 und perlunicode zu verweisen.

Konvertierungs-Script

Mein Script nimmt eine Liste von Datei- und Verzeichnisnamen entgegen benennt alle Dateien in den Verzeichnissen und Unterverzeichnissen in UTF-8 um. Zudem ändert es auch die Dateinamen in .md5 und .sfv Dateien. Es beachtet dabei auch mehrfache falsch-Konvertierungen wie Eingangs beschrieben, indem es sich an Hand einer Zeichen-Bewertung die schönste Konvertierung heraus sucht. Die Präferenzen, was schön ist und was nicht muss von Nation zu Nation angepasst werden. Für Deutsche ist im Dateinamen ein Umlaut schöner als ein ´ schöner als ein Ž. Kroaten mögen andere Zeichensätze bevorzugen und das Ž höher als Umlaute und ´ bewerten.

Es bleibt jedem überlassen, wie er sich das Script anpasst. Getestet werden sollte es allerdings erstmal in einem kleinen Verzeichnis von dem man ein Backup angelegt hat.
Herunterladen kann man es unter

http://download.entropie.li/perl/recode.pl.txt