Skip to content

freiesMagazin für 09/2015 erschienen

Gestern ist die September Ausgabe (09/2015) vom freiesMagazin erschienen,
hier mal ein kurzer Überblick über die Themen, die Ausgabe könnt ihr über den oberen Link in verschiedenen Versionen downloaden.

Inhalt der Ausgabe
* Fedora 22
* OpenBSD – Einmal Kugelfisch, bitte.
* Projektvorstellung: Distrochooser
* Der August im Kernelrückblick
* Spiele-Kurzvorstellung aus dem Humble PC & Android Bundle 13
* Review: bq Aquaris E5 – Ubuntu Edition
* Rezension: Python GE-PACKT
* Rezension: Das Sketchnote-Handbuch
* Rezension: PHP 5.6 und MySQL
* Rezension: Meteor
* Rezension: NFC mit Android und Arduino
* Leserbriefe und Veranstaltungen

Logdaten mittels SQLite erfassen

Der nachfolgende Snippet war der Anfang einer kleinen Logklasse für meine damals entwickelte Toolbox für ProEngineer,
dies war nur eine ganz einfach Klasse, welche noch ausgebaut werden sollte, wozu es aber nie kam.
Ich werde mich hiermit später einmal wieder beschäftigen, sollte ich wieder ein PHP-Skript schreiben,
was zwar geplant aber bisher an der Zeit gescheitert ist, da es nur ein sehr grober Entwurf ist und außerdem
mir die Zeit fehlt.

Vielleicht hilft dieses Snippet irgendjemandem mal so etwas in der Richtung zu verwirklichen, bzw die Klasse etwas besser
auszubauen und eventuelle Verbesserungen darin einzubringen.

class Log
{
        private $query = '';

        function Set ( $text )
        {
                self::Query ( $text );
        }


        private function Query ( $type , $message )
        {
                $text = 'Meldung aufgetreten in: ' . chr ( 10 ) .$_SERVER['PHP_SELF'] . chr ( 10 ) . chr ( 10 ) . $message;
                $date = time ( );
                $text = SQLite3::escapeString ( $text );
                $this->query .= "INSERT INTO log ( logDate, logText ) VALUES ('" . $date . "', '" . $text . "');";
        }

        function Commit ( )
        {
                $filename = PFAD_und_DATEINAME_zur_LOGDB;
                $create = ( file_exists ( $filename ) ) ? 0 : 1;

                $db = new SQLite3 ( $filename );

                if ( $create == 1 ) $db->query ( "CREATE TABLE [log] ( [logDate], [logText] )" );
                $db->query ( "BEGIN;" . $this->query . "COMMIT;" );
                $this->query = '';
                $db->close ( );
        }
}

einfache BBCode Klasse

So nun hier das erste Tutorial aus meiner ProE Toolbox, dies ist eine ganz einfache BBCode Klasse,
also außer den üblichen Formatierungen wie fett, kursiv und unterstrichen,
enthält diese Klasse nur noch zwei Linkvarianten.

Diese Klasse ist natürlich stark ausbaufähig, es sollten noch einige BBCodes hinzukommen,
sowie eine Änderung des Textes ohne erneuten Aufruf mittels new.
Wenn ich mal etwas mehr Zeit habe werde ich diese Klasse noch etwas erweitern.

class BBCode
{
        var $text = '';
        var $search = array ( );
        var $replace = array ( );
        var $convert = false;

        function __construct ( $text )
        {
                $this->text = $text;
                self::Add ( '/\[b\](.*?)\[\/b\]/is' , '<b>${1}</b>' );
                self::Add ( '/\[i\](.*?)\[\/i\]/is' , '<i>${1}</i>' );
                self::Add ( '/\[u\](.*?)\[\/u\]/is' , '<u>${1}</u>' );
                self::Add ( '/\[link\](.*?)\[\/link\]/is' , '<a href="${1}" target="_blank">${1}</a>' );
                self::Add ( '/\[link=(.*?)\](.*?)\[\/link\]/is' , '<a href="${1}" target="_blank">${2}</a>' );
        }

        function Add ( $search , $replace )
        {
                $this->search[] = $search;
                $this->replace[] = $replace;
        }

        function Convert ( )
        {
                if ( $this->convert === false )
                {
                        $this->text = preg_replace ( $this->search , $this->replace , $this->text );
                        $this->convert = true;
                }
        }

        function Get ( )
        {
                self::Convert ( );
                return $this->text;
        }
}


So wird diese Klasse eingesetzt:
$txt = new BBCode ( '[b]mein formatierter Text[/b]' );
// eigene BBCodes können über diese Zeile hinzugefügt werden
// $txt->Add ( RegEx , Ersetzung );
// oder aber ihr tragt das ganze direkt in __construct ein
$txt->Convert ( );
echo $txt->Get ( );

Arbeiten mit SQLite3

SQLite 3 ist nur noch als OOP Variante vorhanden, das macht die Arbeit vielleicht etwas gewöhnungsbedürftig (zum Anfang hin), sollte bisher nur prozedurale Programmierung genutzt worden sein.

$db = new SQLite3 ( 'meine_db.sqlite3' [, int $schalter ]  );
$result = $db->query ( $querystring );
$data = $result->fetchArray();
$db->close ( );

für $schalter sind folgende Konstanten möglich:
SQLITE3_OPEN_READONLY öffnet die Datenbank nur zum Lesen
SQLITE3_OPEN_READWRITE öffnet die Datenbank zum Lesen und Schreiben
SQLITE3_OPEN_CREATE erzeugt eine Datenbank, wenn diese nicht existiert
sollte $schalter leer sein, wird der Standard SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE genommen.

Mit new erzeugen wir ein neues Objekt der Klasse SQLite3 mit den übergebenen Parametern.

$db->query ( ) => erzeugt ein Objekt der Klasse SQLite3Result dieses übergeben wir dem Parameter $result

Nun können wir über $result->fetchAll ( [int $mode] ) die Daten abrufen, wenn nur ein Datensatz erwartet wird nehmen wir die obige Zeile, bei mehreren muss eine Schleife genutzt werden (z.B. while ).

Bei fetchAll kann noch ein Parameter übergeben werden, welcher steuert wie die Daten ausgegeben werden sollen.
SQLITE3_ASSOC gibt ein Array aus welchen als Index-Wert den Spaltennamen nutzt
SQLITE3_NUM gibt ein Array aus welchen als Index-Wert die Spaltenzahl nutzt (Zählung startet bei 0)
SQLITE3_BOTH gibt ein Array aus welches SQLITE3_ASSOC und SQLITE3_NUM entspricht

Über $db->close ( ) schließen wir die Datenbankverbindung wieder.

Arbeiten mit SQLite2

Zuerst muss sichergestellt werdne, ob SQLite überhaupt verfügbar ist, dies erfragt man am Besten beim Webhoster direkt. Ist PHP5 installiert sollte SQLite funktionieren, dies ist allerdings keine Garantie dafür, da SQLite nur ein Zusatzmodul ist und der Hoster dies aus verschiedenen Gründen deaktiviert haben könnte.

$db = sqlite_open('Datei.sqlite',0666,$error);
  # Hier kommen später die Abfragen und der Programmcode rein
sqlite_close($db);


Mit sqlite_open öffnen wir die Datei, die unsere Tabellen enthalten, er wird mindestens 1 Parameter benötigt (Dateiname), optional können die Rechte für den Dateizugriff und eine Variable für die Fehlerbehandlung angegeben werden. Der zweite Parameter funktioniert im Moment noch nicht, da sich SQLite noch im Anfangsstadium befindet.
Diese Funktion übergeben wir eine Variable, diese dient uns als Filehandle um mit den Querys oder später mit sqlite_close() die richtige Datenbank Datei anzusprechen.

Über sqlite_close() wird die Datei wiedergeschlossen.

Als nächstes folgt eine Abfrage aus der Datenbank (dieses Beispiel ist quick'n'dirty!!)

$db = sqlite_open('Datei.sqlite',0666,$error);
$q = sqlite_query($db, "SELECT * FROM test");
 if(sqlite_num_rows($q))
 {
  while($abfrage = sqlite_fetch_array($q))
  {
   print_r($abfrage);
  }
 }
sqlite_close($db);


Wir führen wie in SQL eine Query aus, diese funktioniert ähnlich wie mySQL und ist auch von den Befehlen her ähnlich (Wichtig: Ein noch großer Nachteil ist bei SQLite, der nicht vorhandene ALTER Befehl, eine bestehende Tabelle kann nur umständlich verändert werden (Tabelle kopieren, alte Tabelle löschen, neue Tabelle erstellen, Kopie in neue Tabelle einfügen)).
Mit sqlite_num_rows ermitteln wir die Zahl der Datensätze, sollte kein Datensatz vorhanden sein könnte noch ein else-Zweig eingefügt werden. Über sqlite_fetch_array erhalten wir das Ergebnis zurück, das Array sieht etwas anders aus als bei mySQL

mySQL
Array ( ['Spalte1'] => ‘Wert1', ['Spalte2'] => ‘Wert2' )

SQLite
Array ( [0] => ‘Wert1', ['Spalte1'] => ‘Wert1', [1] => ‘Wert2', ['Spalte2'] => ‘Wert2' )

Also im Gegensatz zu mySQL werden die Datensätze bei SQLite nicht nur nach Spaltennamen sondern auch nach nummerischer Reihenfolge gespeichert (dies hat Vor- und Nachteile)

Nachdem die Grundlagen besprochen wurden, gilt es den wichtigsten Befehlssatz zu erlernen.

SELECT &#42; FROM tabelle WHERE Bedingung = 'test' LIMIT 1


Mit SELECT startet eine Abfrage von Datensätzen, gefolgt von den Spaltennamen bzw. * für alle Spalten.

Durch FROM legen wir fest aus welcher Tabelle gelesen wird.

Die WHERE Bedingung ist optional, es können mehrere Bedingungen mit AND oder OR verbunden werden (AND bindet stärker als OR) und die Bedingungen können nicht nur = (gleich) sein, sondern auch != (nicht gleich), like oder not like.
Bei den letzten zwei Arten sollte mit dem Platzhalter % gearbeitet werden um ein richtiges Ergebnis zu erhalten.

Mit Hilfe von LIMIT werden die Suchergebnisse eingeschränkt oder z.B. bei UPDATE oder DELETE Befehlen die betroffenen Datensätze eingeschränkt.
LIMIT 1 = 1 Datensatz, vom allerersten Datensatz an
LIMIT 1,1 = 1 Datensatz, vom 1 Datensatz (0 wäre der erste Datensatz)

INSERT tabelle (Bedingung) VALUES ('test')

INSERT fügt einen neuen Datensatz in die Tabelle tabelle ein und belegt die Zelle Bedingungen mit dem Wert test

UPDATE tabelle SET Bedingung = 'kein Test'

UPDATE ändert den Datensatz, in diesem Beispiel wären alle Daten aus der Tabelle betroffen, es sollte auf jedenfall mit WHERE und LIMIT gearbeitet werden.

DELETE FROM tabelle

DELETE löscht einen Datensatz, in diesem Fall wird die gesamte Tabelle geleert, auch hier sollte mit WHERE und LIMIT gearbeitet werden.

Ein wichtige Hinweis noch zum Schluss:
SQLite ist zwar praktisch, da kein Datenbank-Server benötigt wird, aber vermeidet es die Daten übers Netzwerk schreiben zu lassen,
es gibt zu viele Störfaktoren und eventuell können Datenverluste auftreten.

simpler Counter mit mySQL

Dieses Tutorial beschreibt, wie ihr einen simplen Counter mit mySQL realisieren könnt.
Wenn ich simpel meine, meine ich auch simpel.
Erzählt nur die täglichen Aufrufe und hat eine IP Sperre mehr nicht ;-)

Das Skript besteht aus 2 Dateien die benötigt werden und 1 Installationsdatei,
die nach das Ausführung gelöscht werden muss !!

counter-config.php
In dieser nehmen wir die Einstellungen für die Datenbankverbindung vor,
sowie das Präfix für die Tabellen und die Reloadsperre

<?php
  $myCounter['dbhost'] = 'localhost'; // Datenbank Host (meist localhost)
  $myCounter['dbuser'] = 'tutorials'; // Datenbank Benutzer
  $myCounter['dbpass'] = 'foobar'; // Datenbank Passwort
  $myCounter['dbname'] = 'tutorials'; // Datenbank Name
  $myCounter['prefix'] = 'counter_'; // Vorsilbe fuer die Tabellen
  $myCounter['reload'] = 86400; // Reloadsperre bevor die IP erneut gezaehlt wird
?>


counter-call.php
Dieses Skript wird in die Anwendung einfach eingebaut, damit werden die Aufrufe gezählt.
So als erstes wird eine Variable $myMainPath erzeugt, diese enthält den absoluten Pfad
zur counter-call.php daraus extrahieren wird den Verzeichnisnamen mit dirname ( )
dadurch kann von überall aus die Datei eingebunden werden, ohne das ein Pfad übergeben werden muss
zur Konfigurationsdatei.

Als nächsten Schritt verbinden wir uns mit der Datenbank.
Jetzt folgt der eigentliche Counter:
Mittels des SELECT Statements ermitteln wir, ob die IP bereits innerhalb von $myCounter['reload'] gezählt wurde.
Wer sich nun über die Angabe INET_ATON wundert, damit wird die IP-Adresse von einem String ( z.B.: 127.0.0.1 )
in einen Integer ( z.B. 2130706433 ) umgewandelt.

Dies hat den Vorteil eventuelle Indizes werden kompakter und effektiver,
da mit Zahlen effektiver gearbeitet werden kann als mit Strings,
außerdem ist der Speicherverbrauch von int ( 10 ) gerade mal 7 Bytes
während varchar ( 15 ) (mit utf8 Zeichensatz) ganze 20 Bytes benötigt.
Klingt jetzt nicht weiter viel, aber macht sich bei gewissen Mengen durchaus bemerkbar.

So nun folgen 2 INSERT und 1 DELETE-Befehl:
Nun müssen wir den aktuellen Tag anlegen bzw. wenn dieser bereits existiert, den Wert um 1 erhöhen.
Da die Spalte `date` einmalig sein muss, setzen wir einen PRIMARY KEY oder UNIQUE KEY darauf,
nun können wir über ON DUPLICATE KEY UPDATE einen UPDATE Befehl ausführen lassen
und sparen uns damit 1 zusätzliches Statement und einige Codezeilen für die Überprüfung, ob der aktuelle Tag bereits angelegt ist.

Das zweite INSERT Statement hat keine besonderen Merkmale.
So nun zum DELETE Statement, es könnten sich einige Fragen was dieses soll :), nun ganz einfach wir wollen doch keine riesigen IP Tabellen erzeugen,
daher löschen wir einfach alle alten IP Einträge aus der Datenbank, auf die die Reloadsperre nicht mehr zutrifft.

<?php
 $myMainPath = dirname ( <u>_FILE_</u> ) . '/';
 require_once ( $myMainPath . 'counter-config.php' );

 if ( $myCounterConn = @mysql_connect ( $myCounter['dbhost'] , $myCounter['dbuser'] , $myCounter['dbpass'] ) )
 {
  if ( @mysql_select_db ( $myCounter['dbname'] , $myCounterConn ) )
  {
   $reload_query = "SELECT ip FROM `" . $myCounter['prefix'] . "ip`
                     WHERE `ip` = INET_ATON('"
. $_SERVER['REMOTE_ADDR'] . "')
                     AND `time` > '"
. ( time ( ) - $myCounter['reload'] ) . "'";
   $reload_query = mysql_query ( $reload_query );
   if ( mysql_num_rows ( $reload_query ) == 0 )
   {

    mysql_query ( "INSERT INTO `" . $myCounter['prefix'] . "visitor`
                   ( `date` , `visitor` ) VALUES ( '"
. date("ymd") . "', '1' )
                    ON DUPLICATE KEY UPDATE `visitor` = `visitor` + 1"
);

    mysql_query ( "INSERT INTO `" . $myCounter['prefix'] . "ip`
                   ( `ip` , `time` ) VALUES ( INET_ATON('"
. $_SERVER['REMOTE_ADDR'] . "') , '" . time ( ) . "')" );

    mysql_query ( "DELETE FROM `" . $myCounter['prefix'] . "ip` WHERE `time` < '" . ( time ( ) - $myCounter['reload'] ) . "'" );
   }
  }
 }
?>


counter-install.php
Dieses Skript installiert die notwendigen Tabellen, nach der Ausführung muss es auf jedenfall wieder gelöscht werden, da dadurch die Tabellen verworfen werden würden.

<?php
 $myMainPath = dirname ( <u>_FILE_</u> ) . '/';
 require_once ( $myMainPath . 'counter-config.php' );

 if ( $myCounterConn = mysql_connect ( $myCounter['dbhost'] , $myCounter['dbuser'] , $myCounter['dbpass'] ) )
 {
  if ( mysql_select_db ( $myCounter['dbname'] , $myCounterConn ) )
  {

   mysql_query ( "DROP TABLE IF EXISTS `" . $myCounter['prefix'] . "ip`" );
   mysql_query ( "CREATE TABLE IF NOT EXISTS `" . $myCounter['prefix'] . "ip` (
           `ip` int(10) unsigned NOT NULL DEFAULT '0',
           `time` int(10) unsigned NOT NULL DEFAULT '0'
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
);

   mysql_query ( "DROP TABLE IF EXISTS `" . $myCounter['prefix'] . "visitor`" );

   mysql_query ( "CREATE TABLE IF NOT EXISTS `" . $myCounter['prefix'] . "visitor` (
           `date` mediumint(6) NOT NULL,
           `visitor` smallint(5) unsigned NOT NULL DEFAULT '0',
           PRIMARY KEY (`date`)
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
);

   echo 'Die Tabellen wurden installiert';

  }
  else
  {

   echo 'Konnte die Datenbank nicht finden';

  }
 }
 else
 {
  echo 'Keine Verbindung zum Server moeglich';
 }
?>


Wie immer übernehme ich keinerlei Haftung für eventuelle Schäden !!

Solltet ihr Verbesserungsvorschläge haben oder Fehler finden, bitte ich um einen kurzen Kommentar, Danke :-)

Updatecheck

Mit diesem Script können Sie überprüfen, ob der User die neuste Version z.B. des Gästebuchs hat.

define('VERSION', '1.2');
define('UPDFILE', 'http://yourdomain.tld/uplink.txt');

  //Version dieser Seite
  $curversion = VERSION;

  if(file_get_contents(UPDFILE))
  {
    if(version_compare(file_get_contents(UPDFILE), $curversion, '&gt;'))
    {
      echo 'Es ist ein neues Update vorhanden!';
    }
    elseif(version_compare(file_get_contents(UPDFILE), $curversion, '='))
    {
      echo 'Das Produkt ist auf dem neuesten Stand!';
    }
    else
    {
      echo 'Fehlerhafte Versionsnummer!';
    }
  }
  else
  {
    echo 'Es konnte keine Verbindung aufgebaut werden!';
  }



define()

Mit dieser Funktion wird eine Konstante definiert. Dies benötigt zwei Parameter: Der Name der Konstante und der Wert, den sie enthalten soll.
Im Gegensatz zu Variablen können Konstanten nicht verändert werden, wie z.B. durch unset

file_get_contents()
Lädt den Inhalt der angegebenen Datei in einen String

version_compare
version_compare benötigt drei Parameter: Der Wert der neuen Version, der Wert der jetztigen Version und das Zeichen >

----

Quelle: Scripting-Base
Die Quelle beinhaltet nur noch ein Portfolio, die ursprünglichen Tutorials sind dort nicht mehr zu finden.

Superglobale Arrays absichern

Die meisten Exploits auf einer Webseite enstehen durch ungesichterte Werte in den superglobalen Arrays $_POST und $_GET.
Dies geschieht entweder durch ein unzureichendes Sanitizing oder durch schlampige Programmierarbeit.
MIt diesem Tutorial soll Ihnen näher gebracht werden, wie dieser Mechanismus automatisiert werden kann.

foreach ($_POST as $key => $value)
{
  $value = strip_tags ($value);
  $value = htmlspecialchars ($value);
  $_POST[$key] = $value;
}


In diesem Code-Segment wird das $_POST-Array mit foreach () durchlaufen. Hierbeit wird $value durch diverse PHP-Funktionen "entschärft", d.h. alle HTML-Tags werden entfernt, Sonderzeichen (<, >>, &, " und ') werden durch ihre HTML-Entitäten ersetzt. Für jedes superglobale Array muss eine eigene foreach-Schleife mit unterschiedlicher Wertebehandlung geschrieben werden. Bei $_GET sollten unter anderem generell alle Sonderzeichen entfernt werden.

Um die Sicherheit des PHP-Programms zu erhöhen, sollte der oben geschriebene Code vor dem ersten Zugriff auf das Array angewendet werden.

----

Quelle: Scripting-Base
Die Quelle beinhaltet nur noch ein Portfolio, die ursprünglichen Tutorials sind dort nicht mehr zu finden.

mySQL Backup mit Hilfe von PHP

Dieses kleine Skript sichert eure Datenbank in eine Datei entweder als normale SQL-Datei oder mit GZip komprimiert.

Ihr müsst lediglich die notwendigen Daten im $myBackup-Array eintragen.

<?php
// mySQL Backup mit Hilfe von PHP
// Licensed under GNU LGPL v3 or later
// Author: Stefan Moosmann
// Homepage: http://www.stefanmoosmann.de/s9y/archives/34-mySQL-Backup-mit-Hilfe-von-PHP.html

$myBackup = array
(
        // Adresse des Datenbankservers (meist localhost)
        'hostname' => 'localhost',

        // Benutzername fuer den Datenbankserver
        'username' => '',

        // Passwort fuer den Datenbankzugang
        'password' => '',

        // Datenbankname
        'database' => '',

        // Tabellen von der Sicherung ausschliessen (nur Struktur wird immer gesichert !!)
        // beim Tabellennamen auf Gross-/Kleinschreibung achten !!
        'notsave' => array ( ),

        // Backup in Datei speichern (bei Komprimierung wird .gz automatisch angehaengt)
        // Sollte den absoluten bzw. relativen Pfad + Dateinamen beinhalten
        'backupfile' => 'backup.sql',

        // Backup Datei mit GZip komprimieren?
        'backupcompress' => true,

        // Daten mit UTF-8 schreiben?
        'backuputf8' => true,
);

mysql_connect ( $myBackup['hostname'] , $myBackup['username'] , $myBackup['password'] );
mysql_select_db ( $myBackup['database'] );

$BackupData  = "-- mySQL Dump\n";
$BackupData .= "-- Host: ".$myBackup['username']."@" . $myBackup['hostname'] . "\n";
$BackupData .= "-- Datenbank: ".$myBackup['database']."\n";
$BackupData .= "-- Erstellungszeit: " . date('d.m.Y H:i:s') . "\n";
$BackupData .= "-- Server Version: " . mysql_get_server_info() . "\n";
$BackupData .= "-- PHP-Version: " . phpversion ( ) . "\n\n";

        $result = mysql_query ( 'SHOW TABLES FROM '.$myBackup['database'] );
        while ( $table = mysql_fetch_row ( $result ) )
        {
                $result_str = mysql_query ( 'SHOW CREATE TABLE `'.$table[0].'`' );
                $structure = mysql_fetch_row ( $result_str );

                $BackupData .= "#\n";
                $BackupData .= "# Struktur von `" . $table[0] . "`\n";
                $BackupData .= "#\n";
                $BackupData .= "DROP TABLE IF EXISTS `" . $table[0] . "`;\n";
                $BackupData .= $structure[1] . ";";
                $BackupData .= "\n\n";

                $BackupData .= "#\n";
                $BackupData .= "# Daten von `" . $table[0] . "`\n";
                $BackupData .= "#\n";

        if ( !in_array ( $table[0] , $myBackup['notsave'] ) )
        {
                $result_data = mysql_query ( 'SELECT * FROM `'.$table[0].'`' );
                while ( $data = mysql_fetch_assoc ( $result_data ) )
                {
                                $insertfull = '';
                                $datastring = '';

                        foreach ( $data as $key => $value )
                        {
                                $insertfull .= '`' . $key . '`,';
                                $datastring .= "'" . addslashes ( $value ) . "',";
                        }
                                $insertfull = '(' . substr ( $insertfull , 0 , -1 ) .')';
                                $datastring = '(' . substr ( $datastring , 0 , -1 ) .')';

                                unset ( $key, $value );

$BackupData .= "INSERT INTO `".$table[0]."` " . $insertfull . " VALUES " . $datastring . ";\n";

                }
        }
        }

if ( $myBackup['backuputf8'] === true ) $BackupData = utf8_encode ( $BackupData );
if ( $myBackup['backupcompress'] === true )
{
        $FileBackup = $myBackup['backupfile'] . '.gz';
        $WriteBackup = gzopen ( $FileBackup , 'w9' );
        gzwrite ( $WriteBackup , $BackupData );
        gzclose ( $WriteBackup );
}
else
{
        $FileBackup = $myBackup['backupfile'];
        $WriteBackup = fopen ( $FileBackup , 'w' );
        fwrite ( $WriteBackup , $BackupData );
        fclose ( $WriteBackup );
}

mysql_close ( );


Das ganze gibt es noch zum Download

Wie immer übernehme ich keinerlei Haftung für eventuelle Schäden !!

Solltet ihr Verbesserungsvorschläge haben oder Fehler finden, bitte ich um einen kurzen Kommentar, Danke :-)

Salted Hash-Generator

Gerade in neueren Internet-Applikationen begegnet man immer wieder sogenannten "gesalzenen Passwörtern". Doch was ist das? Salted Hashes sind im Prinzip zwei gehashte Werte, die zusammengekettet werden und anschließend noch einmal gehasht werden.

Der erste Wert ist meistens das Passwort, der zweite Wert ein zufällig genertierter.
Wie solch ein Generator funktioniert, wird mit diesem Tutorial demonstriert.

function generatePasswd ($length = 8, $salt = 12)
  {
    $pwd = '';
    $md5 = array ();
    $sha1 = array ();

    // Alle ASCII-Zeichen
    $chars = array ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');

    // Zufällig ein Zeichen gross schreiben
    for ($i = 0, $size = count ($chars) -1; $i< $size; ++$i)
    {
      $rand = mt_rand (0, 1);

      if ($rand == 1)
      {
        $chars[$i] = strtoupper ($chars[$i]);
      }
    }

    $numbers = array ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');

    // Sonderzeichen einbinden
    $specialChrs = array ('!', '§', '$', '%', '&', '-', '_', ',', ';', ':', '.',
                          '@', '#', '*', '+', '~');

    // ASCII-Zeichenarray mit dem der Sonderzeichen zusammenfuehren
    $pwdChrs = array_merge ($chars, $numbers, $specialChrs);

    // Passwort mit Laenge $length zusammensetzen
    for ($i = 0; $i< $length; ++$i)
    {
      $rndChr = mt_rand (0, count ($pwdChrs) -1);
      $pwd .= $pwdChrs[$rndChr];

      // Entferne gesetztes Zeichen um doppelte Vorkommen zu vermeiden
      unset ($pwdChrs[$rndChr]);
    }

    $saltIndex = uniqid ('', time () );

    // Salted MD5-Hash
    $md5['hash'] = md5 ($pwd);
    $md5['salt'] = substr (md5 ($saltIndex), 0, $salt);
    $md5['salted'] = md5 ($md5['hash'].$md5['salt']);

    // Salted SHA1-Hash
    $sha1['hash'] = sha1 ($pwd);
    $sha1['salt'] = substr (sha1 ($saltIndex), 0, $salt);
    $sha1['salted'] = sha1 ($sha1['hash'].$sha1['salt']);

    return array ($pwd, $md5, $sha1);
  }

  $passwd = generatePasswd ();


Klartext:<?php echo $passwd[0] ?><hr />
MD5:<?php echo $passwd[1]['hash'] ?><br />
Salt:<?php echo $passwd[1]['salt'] ?><br />
Salted MD5:<?php echo $passwd[1]['salted'] ?><hr />
SHA1:<?php echo $passwd[2]['hash'] ?><br />
Salt:<?php echo $passwd[2]['salt'] ?><br />
Salted SHA1:<?php echo $passwd[2]['salted'] ?><hr />
 


Die Funktion "generatePasswd" besitzt zwei Parameter, welche jedoch optional sind: $length bestimmt die Länge des Passworts, $salt bestimmt die Länge des Salt-Wertes.
Das Array $chars beinhaltet das Standardalphabet, das in jedem ASCII-Zeichensatz auftaucht, $numbers beinhaltet alle Zahlen von 0 bis 9 und $specialChrs enthält einige Sonderzeichen, die für ein Passwort geeignet sind.

In der ersten for ()-Schleife wird das $chars-Array durchlaufen und zufällig werden einige Zeichen in Großbuchstaben konvertiert.
Nun werden die drei Zeichen-Arrays zu einem gemeinsamen Array zusammengesetzt.
In der zweiten for ()-Schleife wird das Passwort aus dem gemeinsamen Array zufällig zusammengesetzt. Beispielsweiße könnte nun der Wert "fT53%-:" herauskommen.

Nun beginnt der eigentliche Hash-Vorgang: Ein zufälliger Wert wird mit der Funktion uniqid () und time () erstellt und in der Variable $saltIndex gespeichert.
Im Array $md5 wird der Schlüssel "hash" mit den normalen MD5-Hash des Passworts gespeichert. Im Schlüssel "salt" befindet sich der gehashte Salt, welcher aus die Länge getrimmt wird, die im Funktionskopf im Parameter $salt gesetzt wurde.
Der eigentliche gesalzene Hash befindet sich im Schlüssel "salted". Dort werden die Schlüssel "hash" und "salt" (die ja bereits gehasht sind) verkettet und anschließend noch einmal gehasht.
Analog funktoniert das mit dem SHA1-Teil.
So ergibt sich selbst bei zwei identischen Passwörtern immer ein anderer End-Hash. Jedoch sollte, damit der End-Hash zu einem Login funktioniert, der reine gehashte Salt, also der Schlüssel "salt" irgendwo gespeichert werden, z.B. in einer Datenbank, da dieser schließlich zum Berechnen des korrekten Hash-Wertes benötigt wird.


----

Quelle: Scripting-Base
Die Quelle beinhaltet nur noch ein Portfolio, die ursprünglichen Tutorials sind dort nicht mehr zu finden.