18
Jun

Bohemian Rhapsody

categories Fundstücke, Musikalien     comments Comments (4)

Respekt…!

28
Mai

Biometrie im Bad Orber Freibad: Provinzposse oder zukunftsweisendes Verfahren?

categories Aktuelles     comments Comments (5)

Im Laufe dieser Woche erfuhr ich via Buschfunk von der Nachricht, dass das Zuganssystem des Freischwimmbades im altehrwürdigen Kurort Bad Orb mit einem Fingerabdruck-Verfahren ausgestattet wurde.

Nicht nur der Buschfunk funktioniert, natürlich wurde das System überparteilich behandelt und erhielt mediale Aufmerksamkeit (Hessischer Rundfunk, Frankfurter Rundschau, Frankfurter Neue Presse, auch Sat1 meldete sich).

Die Stadt will vorrangig vermeiden, dass die personengebundenen Dauerkarten missbraucht werden und durch den Zaun an andere Schwimmbadbesucher durchgereicht werden. Außerdem sollen Personalkosten an Kassen reduziert werden. Eigentlich eine gute Idee, oder?

Der Einsatz des Fingerabdrucks jedoch weckte den Datenschutz-Drachen. Politiker, Juristen, Datenschützer melden sich zu Wort und kritisieren das Verfahren.

Die Diskussion amüsiert mich ein wenig, denn sie verläuft öffentlich derzeit sehr oberflächlich. Bei all dem Gerede vermisse ich eine klare Beschreibung, wie es technisch denn nun genau funktioniert. Ein Indiz fand ich in einem Artikel, darin hieß es, dass die Daten schließlich nicht zentral gespeichert, sondern nur auf dem Chip vorliegen würden. Das sagt nicht viel.

Wie wäre es garantiert nicht sauber?
Auf dem Chip sind (womöglich im Klartext) die Merkmale vom Fingerabdruck des Trägers gespeichert. Bei der Prüfung am Fingerabdruck-Scanner fragt dieser die gescannten Merkmale bei einen Server an, auf welchem die Merkmale auch gespeichert sind.

So bitte nicht. Wenn die Technik so funktioniert, schlage ich mich sofort auf die Seite der Datenschützer. Provinzposse.

Wie wäre es sauber?
Auf dem Chip ist ein Hashwert für die Merkmale des Trägers gespeichert. Bei der Prüfung am Fingerabdruck-Scanner bildet das Gerät ebenso einen Hashwert der Merkmale und vergleicht das Ergebnis mit dem Chip. Die Merkmale selbst werden gar nicht gespeichert, sondern nur zur Ermittlung des Hashwerts verwendet.

Falls dies hinter dem Verfahren steht, gut gemacht! So gehts, so ist es in Ordnung.

Ein Hashwert kann natürlich geknackt werden, damit hätte man das System gehackt, aber dennoch nicht die dem Hash zugrunde liegenden Daten des Fingerabdrucks. Was hätte der Angreifer davon? Er hätte Zugang ins Freibad! Dafür lohnen sich hochkomplexe Hashwert-Attacken…

Zuletzt im Hackerclub:
Hacker-Azubi zum Chef:
„Nun versuchen wir uns an Biometrie. Was hacken wir jetzt? Den Personalausweis? Bankensysteme? Zugriffe zu High-Security-Gebäuden? Atomkraftwerke? Rüstungskonzerne?“

Chef:
„Nein…viel besser… wir hacken das Bad Orber Freibad!“

Wem das zuviel Sarkasmus ist… sorry! 😉

Ich würde mich freuen, wenn das Verfahren etwas genauer beschrieben wird. Dann könnte man sich ein gesundes Bild davon machen, ob es sich hierbei um eine Provinzposse oder um ein zukunftsweisendes Verfahren handelt.

23
Mär

Modultests mit PHPUnit

categories Computer, PHP, Tutorials     comments Comments (0)

Eine kleine private Exkursion in die Tiefen einer OpenSource-Gemeinde hat mir mal wieder vor Augen gehalten, wie man sich das Coder-Dasein durch die Verwendung von Modultests („UnitTests“) vereinfachen kann. Nicht jeder benutzt sie, jeder sollte. In der PHP-Programmierung ist die ideale Software hierfür PHPUnit.

Die Software wird im GitHub verteilt, ist gut dokumentiert, weit verbreitet (guckt mal in viele größere Klassen rein, man stolpert oft über den einen oder anderen Testordner) und genießt hohes Ansehen bei Entwicklern. Die Software ist auch im PEAR und kann darüber installiert werden (ein paar Dependencies gibt es für zusätzliche Funktionen).

An einem einfachen Beispiel möchte ich die grundsätzliche Verfahrensweise demonstrieren. Angenommen, in einem PHP-Projekt gibt es irgendwo eine Funktion, welche den Ostersonntag eines Jahres bestimmt. Der Einfachheit halber nennen wir sie easter($jahr). So eine Funktion könnte beispielsweise eingebunden sein, wenn es um die Errechnung von verschiedenen Feiertage geht – somit könnte sie eine gewisse Kritikalität im Projekt innehaben. Wie testet man nun so eine Funktion mit PHPUnit?

Ich steige hier mal mitten in PHPUnit ein:

require_once 'includes/functions.php';
 
class EasterTest extends PHPUnit_Framework_TestCase {
  public function testEasterOk() {
    $easter2011 = easter(2011);
    $this->assertEquals($easter2011, gmmktime(0,0,0,4,24,2011));
  }
 
  public function testEasterFalse() {
    $easter2011 = easter(2011);
    $this->assertNotEquals($easter2011, gmmktime(0,0,0,12,24,2011));
  }
} 

Zuerst habe einen Verweis auf das PHP-Script (hier: functions.php), in welcher die Funktion easter($Jahr) enthalten ist. Dann generiere ich eine Klasse („EasterTest“), welche PHPUnit erweitert. In dieser Klasse sind zwei Tests abgelegt:

Jetzt kommt der trockene theoretische Teil…
Hier geht es nicht etwa darum, das Ergebnis zu finden – das hat man ohnehin schneller mit einem Blick auf dem Kalender. Vielmehr ist es Ziel, das Ergebnis der Funktion mit einem definierten „Wunschergebnis“ zu vergleichen. Ich weiß, dass der 24.04. dieses Jahr der Ostersonntag ist… und ich weiß, dass es der 24.12. definitiv nicht ist.

PHPUnit – wie auch fast alle andere Software in diesem Umfeld – arbeitet mit „Assertions“ (Behauptungen). Es gibt eine Sammlung von einfachen Funktionen, welche solche Assertions in verschiedenen Konstrukten ermöglichen – angefangen von Vergleichsoperationen wie die im Beispiel verwendeten assertEquals und assertNotEquals über False/True-Varianten, Array-Prüfern und einigem anderen.

Ist dies viel Arbeit?
Bitte urteilt selbst.. ein einfacher Test ist fix geschrieben. Nicht schwer, oder?

Zurück zur Praxis.
Wie kann man nun die Tests auswerten? Am einfachsten über die Shell. Und hier ist es nun wirklich egal, ob man sich in einer Dosbox, Bash oder wo auch immer aufhält.

D:\htdocs\>phpunit EasterTest.php
PHPUnit 3.5.11 by Sebastian Bergmann.

..
 
Time: 0 seconds, Memory: 3.75Mb
 
OK (2 tests, 2 assertions)

PHPUnit kann auch andere Output-Formate, beispielsweise das TAP-Format („Test Anything Protocol“), JSON, XML und andere.

D:\htdocs\>phpunit --tap EasterTest.php
TAP version 13
ok 1 - EasterTest::testEasterOk
ok 2 - EasterTest::testEasterFalse
1..2

Wenn ich nun in einem Test einen Fehler habe, sieht das so aus (ich habe hierfür den Test 1 so verändert, dass die Behauptung lautet, der 23.04.2011 wäre Ostersonntag – ist aber in Wirklichkeit der Samstag davor):

D:\htdocs\>phpunit --tap EasterTest.php
TAP version 13
not ok 1 - Failure: EasterTest::testEasterOk
  ---
  message: 'Failed asserting that <integer:1303516800> matches expected <integer:1303603200>.'
  severity: fail
  data:
    got: 1303516800
    expected: 1303603200
  ...
ok 2 - EasterTest::testEasterFalse
1..2

Wenn ich nun – wann und warum auch immer – an der eigentlichen Funktion wieder mal arbeite, dann habe ich weiterhin meine gespeicherten Tests. Wenn diese mir also Mist zurückgeben, ist entweder mein Test falsch (eher unwahrscheinlich), oder meine veränderte Funktion ist nicht ok… und genau darum geht es hier. Modultests wie dieser hier machen den Code deutlich stabiler und nachträgliche Arbeiten, Erweiterungen etc. erheblich einfacher.

Und wenn es mal Bugs gibt… schreibt einen Test und fixt dann den Bug!

8
Mär

qTranslate

categories Computer     comments Comments (0)

Ich teste gerade qTranslate. Mal sehen, wie das funktioniert!

5
Mär

PHP-Commandline-Parameter mit Console_Getopt

categories PHP, Tutorials     comments Comments (0)

Aus der Historie heraus verwenden die meisten Entwickler PHP hauptsächlich als serverseitige Skriptsprache zur Erstellung von Webseiten oder Webanwendungen. Mit PHP kann man jedoch noch viel mehr machen: es bietet ein Commandline-Interface, welches ermöglicht, auch unter verschiedenen OS Shell-Scripts zu schreiben und zu verwenden.

Um übergebene Parameter auszuwerten, bedient man sich der dafür reservierten Variable $argv.

Beispiel 1: test_argv.php

<?php
var_dump($argv);
?>

Ausgabe von Beispiel 1:

d:\php5> php.exe test_argv.php IchBinParam1 UndIch2
array(3) {
  [0]=>
  string(13) "test_argv.php"
  [1]=>
  string(12) "IchBinParam1"
  [2]=>
  string(7) "UndIch2"
}

So weit, so gut. Wenn es jetzt darum geht, die Argumente zu parsen und zu prüfen, kann so ein Konstrukt rund um $argv schnell recht aufwändig werden. Um dies zu erleichtern, gibt es im PEAR-Paket eine kleine Klasse namens Console_Getopt.

Installation
Falls man PEAR verwendet, kann man die Klasse sehr einfach darüber installieren.

d:\php5> pear install Console_Getopt-1.3.0

Man ist jedoch nicht darauf angewiesen. Es reicht vollkommen aus, die Klasse von der offiziellen PEAR-Seite zu downloaden und in das Projekt einzubinden.

Anwendung
Die Anwendung ist denkbar einfach. Man bindet die Klasse in das eigene Programm ein, initialisiert das Klassenobjekt, definiert erlaubte Optionen und prüft dann die übergebenen Parameter.

Hier ein einfaches Beispiel zur Anwendung.

Beispiel 2: demo_getopt.php

<?php
// Klasse einbinden
include ("Getopt.php");

// Klasse initialisieren
$cg = new Console_Getopt();

/** 
 * Erlaubte Optionen:
 * -a Abba
 * -b Beatles
 * -q Queen
 */
$allowedOptions = "abq";

// Kommandozeile lesen
$args = $cg->readPHPArgv();

// Optionen herausfiltern
$ret = $cg->getopt($args, $allowedOptions);

// Errorhinweis
if (PEAR::isError($ret)) {
    die ("Fehler in Kommandozeile: " . $ret->getMessage() . "\n");
}

// Ausgabe der Optionen
print_r($ret);
?> 

Ausgabe zu Beispiel 2:

d:\temp\getopt>php.exe demo_getopt.php -ab Who Genesis
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => a
                    [1] =>
                )

            [1] => Array
                (
                    [0] => b
                    [1] =>
                )

        )

    [1] => Array
        (
            [0] => Who
            [1] => Genesis
        )

)

d:\temp\getopt>d:\php5\php.exe demo_getopt.php -c
Error in command line: Console_Getopt: unrecognized option -- c

Nach dem Filtern der Optionen kann man nun die über die Kommandozeile eingebenen Parameter auswerten und weiter verarbeiten.

Beispiel 3: demo_getopt_erweitert.php

.
.
.
// Optionen herausfiltern
$ret = $cg->getopt($args, $allowedOptions);

$optionen = $ret[0];
if (sizeof($optionen) > 0) {
    // mindestens eine Option wurde gewählt
    foreach ($optionen as $o) {
        switch ($o[0]) {
            case 'a':
                echo "gewählte Band: Abba\n"; 
                break;
            case 'b':
                echo "gewählte Band: Beatles\n"; 
                break;
            case 'q':
                echo "gewählte Band: Queen\n"; 
                break;
        }
    }
} 

Die Klasse kann noch mehr, unter anderem ist es z.B. möglich, notwendige und optionale Parameter definieren. Auch kann man definieren, ob Parameter Zeichenketten oder Zahlenwerte sein dürfen.

Wer einen tieferen Einblick in die Klasse möchte, die Klasse selbst ist gut dokumentiert. Einen ausführlichen und guten Artikel mit weiteren Anwendungsbeispielen gibt es hier bei Zend.

« Vorherige SeiteNächste Seite »