Mein Ausflug in den Naturpark Sparbach
TCaptcha - Einfache Einbindung von Captcha-Codes ueber PHP
Das ist der erste Co- Authoren Beitrag auf meiner Seite zum Thema Captchas.
Vielen Dank vorab an: Sereby (http://www.sereby.org/)
Man findet Sie überall und man kommt auch nicht mehr dran vorbei:
Captcha's (Completely Automated Public Turing test to tell Computers and Humans Apart)
Sie werden von Webseiten-Administratoren z.B. bei Kontaktformularen, Shoutboxen oder Downloads verwendet, um sicher zu stellen, dass Bots nicht die Möglichkeit haben die Shoutbox oder ähnliches voll zu spammen oder in einem Downloadbereich dafür zu sorgen, dass nicht unendlich viel Traffic verbraucht wird, weil der Downloadlink tausende Male ausgeführt wird.
Nun zum eigentlichen Code:
Download
zunächst muss die Klasse TCaptcha eingebunden werden um auf die Validierungsfunktionen zuzugreifen
Code
<?
include('captchaTCaptcha.php');
?>
<form action="" method="post" name="111">
<!--
Einbinden des Captcha's über ein <img> tag.
Wenn mehrere Captcha's verwendet werden sollen, dann
müssen Sie die ID verändern!
-->
<img src="captcha/show.php?id=1" alt="Sicherheitscode 1" />
<input type="text" name="captcha_code1" size="13" /> <input type="submit" value="OK" />
<?
//code überprüfen
if (isset($_POST['captcha_code1'])){
// Validate(* Getippter Code *, * Captcha-ID die verglichen werden soll *)
if (TCaptcha::Validate($_POST['captcha_code1'], 1)){
echo 'Code OK!';
}else{
echo 'Falscher Code eingegeben!';
}
}
?>
</form>
<?php
session_start();
define('CAPTCHA_SESSION_ID', 'php_captcha');
define('CAPTCHA_IGNORE_CASE', false);
class TCaptcha
{
var $IgnoreCase;
var $CharSet;
var $font;
var $font_size;
var $width;
var $height;
var $bgimg;
var $maxlen;
public $Code;
public function __construct($FontFile = './xfiles.ttf', $iWidth = 100, $iHeight = 40)
{
$this->IgnoreCase = CAPTCHA_IGNORE_CASE;
$this->font = $FontFile;
$this->bgimg = './bg.png';
$this->maxlen = 5;
$this->font_size = 20;
$this->CharSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$this->SetWidth($iWidth);
$this->SetHeight($iHeight);
$this->Code = '';
}
function SetWidth($iWidth)
{
$this->width = $iWidth;
if ($iWidth > 500) $this->width = 500;
}
function SetHeight($iHeight)
{
$this->height = $iHeight;
if ($iHeight > 200) $this->height = 200;
}
private function randomString($len)
{
//zufallszahl
function make_seed()
{
list($usec , $sec) = explode (' ', microtime());
return (float) $sec + ((float) $usec * 100000);
}
srand(make_seed());
//zufallsstring
$str = '';
while (strlen($str)<$len)
{
$str .= substr($this->CharSet, (rand()%(strlen($this->CharSet))), 1);
}
return($str);
}
function GenerateCode()
{
//captcha-id
$CaptchaID = (is_numeric($_GET['id']) ? $_GET['id'] : '1');
//code generieren
$this->Code = $this->randomString($this->maxlen);
//groß / kleinschreibung beachten?
if ($this->IgnoreCase)
{
$this->Code = strtoupper($this->Code);
}
//in die Session schreiben
$_SESSION[CAPTCHA_SESSION_ID][$CaptchaID] = $this->Code;
}
function Create()
{
//Hintergrundbild einlesen
$picinfos = GetImageSize($this->bgimg);
$OldIMG = ImageCreateFromPNG($this->bgimg);
//größe anpassen
$img = ImageCreateTrueColor($this->width, $this->height);
ImageCopyResized($img,$OldIMG,0,0,0,0,$this->width,$this->height,$picinfos[0],$picinfos[1]);
//Farbe der Schrift
$color = ImageColorAllocate($img, 0, 0, 0);
//ZufallsCode generieren
$this->GenerateCode();
//justierung
$spacing = ($this->width / $this->maxlen);
$t_y_min = min($this->height, $this->font_size);
$t_y = rand($t_y_min / 1.2, $t_y_min / 2.8) + $spacing;
$angle = rand(0,7);
$t_x = rand(5,10);
$a = 0;
//text auf das bild schreiben. Zeichen für Zeichen
for ($i = 1; $i <=$this->maxlen; $i++)
{
ImageTTFText($img, $this->font_size, $angle, $t_x, $t_y, $color, $this->font, $this->Code{$a});
$t_x = $t_x + $spacing -3;
$a++; // nächstes zeichen
}
//bild anzeigen
header("Content-type: image/gif");
ImageGIF($img);
//bild freigeben
ImageDestroy($img);
}
function Validate($MyCode, $ID = 1, $IgnoreCase = CAPTCHA_IGNORE_CASE)
{
if ($IgnoreCase)
{
$MyCode = strtoupper($MyCode);
}
if (!empty($_SESSION[CAPTCHA_SESSION_ID][$ID]) && $MyCode == $_SESSION[CAPTCHA_SESSION_ID][$ID])
{
unset($_SESSION[CAPTCHA_SESSION_ID][$ID]); //wiederbenutzen vermeiden
return true;
}
return false;
}
}
?>
Wie funktioniert eigentlich ein Redirect Service
Was ist ein Redirect Service ?
Ein Redirect oder auch Alias Service ist eine Methode, mit der man aus einer langen Internetadresse, eine gekürzte Form machen kann ...
Bsp.:
Aus
http://maps.google.at/maps?hl=de&ie=UTF8&ll=48.203397,16.373062&spn=0.094503,0.305557&z=12
Wird
http://kickmeto.ath.cx/wien
Nötig wird so ein Service, wenn man bei der Zeilenlänge eingeschränkt ist,
wie etwa in einer eMail, bei einer SMS oder auch bei Twitter.
Was benötigen wir für unseren eigenen Redirect Service ?
Eine möglichst kurze Domain
Einen Webserver mit PHP und mod_rewrite (Apache)
Eine Datenbank (im Beispiel verwende ich MySQL)
Ich habe zum Demonstrieren http://kickmeto.ath.cx/ online gestellt, was
auf folgendem Code basiert.
Zuerst erstellen wir unsere MySQL Tabelle "redirect":
CREATE TABLE `redirect` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`url` text NOT NULL,
`name` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Hier haben wir einen primären Schlüssel (id), die Adresse (url) welche wir in den Namen (name) umwandeln möchten.
Jetzt erstellen wir eine Konfigurationsdatei, in der wir unsere Datenbankparameter, wie user, passwort etc.
reinschreiben:
Code
<?
/*** mysql connection information ****/
/*****************************************/
$db = "redirect";
$db_host = "localhost";
$db_user = "user";
$db_pass = "pass";
$url = "http://kickmeto.ath.cx/";
/*****************************************/
?>
<?
include("./config.php");
$sOut="";
//wir bauen eine verbindung zur datenbank auf
$connect=@mysql_connect("$db_host", "$db_user", "$db_pass")
or die("<li>Cant connect to: $db_host with user: $db_user</li>");
@mysql_select_db($db, $connect)or die("Cant select DB");
//im folgenden teil versuchen wir einen redirect in der datenbank zu finden
//wenn nicht das eingabe formular gefragt ist
if($_SERVER[REQUEST_URI]!=="/"){
$surl=mysql_escape_string(strip_tags(substr($_SERVER[REQUEST_URI], 1)));
$sql='select url from redirect where name="'.$surl.'" or id="'.$surl.'" limit 1';
$query=mysql_query($sql);
$row=mysql_fetch_array($query);
if($row[url]){
//hier paasiert die eigentlich weiterleitung
header("Location: $row[url]");
}else{
$sOut.= "Kurzadresse nicht gefunden";
}
}
//wenn jemand speichern drückt
if($_POST){
//überprüfe ob die url syntax richtig ist
if(preg_match("/(((https?)|(ftp))://([-w]+.)+w{2,3}(/[%-w]+(.w{2,})?)*(([w-.?\/+@&#;`~=%!]*)(.w{2,})?)*/?)/i", $_POST[url])){
//maskiere die parameter und speichere sie in die datenbank
$nurl=mysql_escape_string($_POST[url]);
if($_POST[name]){
$sqlstr="'".mysql_escape_string(strip_tags($_POST[name]))."'";
$name=mysql_escape_string(strip_tags($_POST[name]));
} else {
$sqlstr="NULL";
}
//hier überprüfen wir ob der name schon existiert
if(url_exist($name)){
$sOut="Der Name existiert leider schon, versuchs mit einem anderem.";
} else {
//nun schreiben wir die neue kurzurl in die datenbank
$sql="insert into redirect VALUES ('', '$nurl', $sqlstr)";
mysql_query($sql);
$id=mysql_insert_id();
$sOut.='Deine Adresse ist nun unter folgender Adresse erreichbar:<br>';
if($_POST[name]){
$sOut.='<a href="'.$url.''.$name.'">'.$url.''.$name.'</a> oder <br>';
}
$sOut.='<a href="'.$url.''.$id.'">'.$url.''.$id.'</a>';
}
}else{
$sOut.="Bitte check deine URL";
}
}
function url_exist($url){
$sql='select url from redirect where name="'.$url.'" or id="'.$url.'" limit 1';
$query=mysql_query($sql);
$row=mysql_fetch_row($query);
if($row[0]){
return true;
} else {
return false;
}
}
?>
<html>
<head>
<style type="text/css">
body{
background-color:#000000;
color: #ffffff;
text-align:center;
}
</style>
</head>
<body>
<div class="header">Banner
Short Url Service
</div>
<div class="msg">
<?=$sOut; ?>
</div>
<form method="post">
<table align="center">
<tr>
<td>Url:</td>
<td><input type="text" name="url" value="http://"></td>
</tr>
<tr>
<td>Name (Optional)</td>
<td><input type="text" name="name"></td>
</tr>
<td> </td>
<td><input type="submit" name="Save" name="Speichern"></td>
</tr>
</table>
</form>
</body>
</html>
Vorratsdatenspeicherung, DNS Blocklisten und andere Wahrnehmungsstoerungen
Generell begrüße ich die Idee das Internet sicherer zu machen, es gibt
viel fragwürdiges Material im Internet, sei es Kinderpornographie,
Rechtsextremismus oder Schadsoftware, doch ich denke nicht, dass der Zweck alle Mittel heiligt.
Man sollte doch stark differenzieren.
Die Tendenz geht immer mehr in eine Richtung die mich persönlich
betrifft, ohne dass ich es direkt bemerke und ohne dass ich jemanden etwas böses
will.
Es hat alles mit dem Deckmantel der Terrorbekämpfung angefangen, ging
weiter mit der Vorratsdatenspeicherung und nun auch noch die DNS Blocklisten...
Zitat:
Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides
verlieren. Benjamin Franklin
Ich persönlich fühle mich in meiner Freiheit sagen wir zumindest
eingeschränkt, da ich jederzeit damit rechnen
muss, überwacht zu werden.
Das klingt etwas paranoid, tatsächlich werden wir aber jeden Tag überwacht,
sei es in der U-Bahn, am Telefon oder beim eMail schreiben...
Wenn ich zum Beispiel eine Recherche im Internet über den Nationalsozialismus
mache, oder meine Freundin am Telefon anrufe, werden meine Daten gesammelt,
verknüpft und von einer Maschine interpretiert.
Datamining heisst das Zauberwort.
Es ist leider in unser Technologie Gesellschaft sehr leicht möglich
persönliche Profile mit wenigen Mausklicks zu erstellen, leider
sind solche Programme relativ dumm (ich weiss das, da ich vergleichbare
Anwendungen programmiere).
Sie nehmen, sagen wir drei Parameter: Wohnort, Alter und Geschlecht und
leiten davon Ihre Lebenserwartung, das durchschnittliche Einkommen und ihre Bonität
ab.
Ein Mobilfunkbetreiber, dessen Namen ich nicht nennen möchte, hat ein
vergleichbares Programm, so kann es sein, dass Sie keinen Handyvertrag bekommen wenn
sie in der falschen Gegend wohnen, da in ihrem Umfeld oder ihr Vormieter die Rechnungen nicht zahlte.
Ich will damit sagen das solche Programme wenig nutzen für die
Gesellschaft bringen, vergleichbar aber enorm fehleranfällig und teuer sind.
Nun werden solche Programme nicht nur von Unternehmen sonder auch vom
Staat benutzt,
die Frage die sich mir dabei stellt, mit welchem Recht hat der Staat die
Befugnisse erhalten soviel über mich zu erfahren ??
Was ist mit dem Fernmeldegeheimnis passiert ?
Ist uns unsere Privatssphäre nicht mehr wichtig ?
Eine DNS Sperre kann nicht ausreichen, da diese den fragwürdigen Inhalt
nicht aus dem Internet verbannt sondern nur eine Art Vorhang für ein bestimmtes Publikum darstellt.
Da ist die bisherige Lösung, das ein Gericht entscheidet, ob eine Seite
wirklich vom Netz geht oder nicht, meines erachtens nach besser.
Ebenso wird keine DNS Sperre Gewalt oder sexuellen Missbrauch an Kindern
verhindern oder unterbinden.
Ich vermute eher dass es in einer Welt wo andere entscheiden was ich sehen
darf und was nicht, schwerer wird sich selbst ein Urteil zu bilden.
https://epetitionen.bundestag.de/index.php?action=petition;sa=details;petition=3860 -Die Petition gegen Internetsperren
http://dip21.bundestag.de/dip21/btd/16/128/1612850.pdf -Der Gesetzentwurf zu den Internetsperren
Wie schreibe ich eine Suchmaschine part 1
Wo sind denn nur die verflixten Schlüssel hin verschwunden? Und wer zur Hölle versteckt ständig die Fernbedienung?!?
Nun ja, wer kennt sie nicht die verzweifelte Suche nach allen möglichen Dingen?
Im realen Leben kann ich euch da auch nicht helfen (obwohl die Marktchancen für Schlüsselsuchroboter wohl gar nicht schlecht wären),
aber im Überlebenskampf in den unendlichen Weiten des www gibt es zum Glück eine Möglichkeit...
Anmerkung:
Wie man eMailadressen, Kreditkarten oder andere personenbezogene Daten aus dem Netz fischt werde ich an dieser Stelle nicht beantworten.
Wer wissen will wie man ansatzweise eine eigene Suchmaschine schreibt, wird hier geholfen,
etwas Programmiererfahrung in PHP wäre dabei von Vorteil.
Überblick:
Ich habe mich schon etwas länger mit der Problematik befasst eine Suchmaschine zu erstellen,
weniger aus der Ambition heraus Google Konkurrenz zu machen, als mehr aus Spass an der Technik.
Zuerst einmal werde ich in diesem Artikel eine kleine Übersicht geben und die Unterschiede zwischen
einem Crawler und Indexer erklären.
In weiterer Folge werden wir versuchen Ordnung ins Chaos zu bringen und eine kleine Suchmaschine programmieren.
Es wird am Ende auch auf das Thema SEO eingegangen, allerdings weniger aus der klassischen Perspektive der
selbsternannten Marketingexperten, als mehr aus Sicht des Suchmaschinenprogrammierers.
Auf dem Markt gibt es derzeit viele Suchmaschinen, allerdings wenige die so populär sind wie Google,
was nicht zuletzt auf deren Rankingfunktion zurückzuführen ist, diese ist dafür verantwortlich
dass ich möglichst relevante Suchergebnisse erhalte.
Wir werden uns also in weiterer Folge mit der Thematik beschäftigen müssen, wie wir möglichst
interessante Ergebnisse zu den Suchanfragen generieren.
Hierbei unterscheide ich generell zwischen zwei Arten, dem usergenerated Ranking (bedeutet der User bestimmt welche Inhalte zu welchem
Thema interessant sind) und dem rein computergestützten Ranking.
Am besten wäre natürlich eine Mischung aus beiden, aber dazu später mehr.
Die erste Frage die sich stellt, wenn man sich mit der Thematik beschäftigt: "Woher bekomme ich die ganzen Daten?".
Das kommt darauf an, was man durchsuchen will, wir werden uns in diesem kleinen Howto primär den Internetdaten widmen.
Also "Woher bekomme ich alle Webseiten?", nun ja, leider ist es bei der Grösse und dem Wachstum des Internets nicht
möglich alle Webseiten in seine Suchmaschine aufzunehmen, auch für Google nicht. (Ja, richtig, entgegegen hartnäckig
kursierender Gerüchte: auch Google weiß nicht alles.)
Daher können wir nur einen kleinen Teil des Internets überhaupt aufnehmen.
Diese Arbeit macht der sogenannte Webcrawler, er besucht Webseiten, folgt den Links (bis zu einer gewissen Tiefe) und
speichert die Daten in einer Datenbank.
Meine ersten Gehversuche habe ich mit einem externen Crawler (larbin und wget) und einem selbst geschriebenen Indexer gemacht.
Der Indexer hat lediglich die Aufgabe gehabt, vereinfacht gesagt die gesammelten Daten in die Datenbank zu schreiben.
In weiterer Folge hat er die Daten sortiert, Schlüsselwörter extrahiert und Datenbestände aktuell gehalten.
Bei grösseren Mengen (Bsp. 30 GB Daten) kann das schon mal an die Grenzen der Serverressourcen gehen.
Deshalb habe ich die Suchanfragen auf einen zweiten Table abgefragt, wo lediglich url, title, keywords und description
vorhanden sind und nicht die gesamten Rohdaten.
Okay was wissen wir bis jetzt? Wir benötigen einen Webcrawler, der uns die Webseiten runterlädt, und
einen Indexer der die Webseiten in die Datenbank speichert. Soweit sogut.
Damit wir unsere Daten nicht nur horten, sondern auch nutzen können, brauchen wir auch noch ein kleines
Frontend, mit der Möglichkeit eine Suchanfrage zu starten.
In meinem Beispiel wird das Frontend auch die Aufgabe des Webcrawlers übernehmen, das bedeutet man
kann nur einzelnene Seiten dem Index hinzufügen, allerdings ist diese Variante auch kompatibel
mit larbin, wget und anderen Webcrawlern.
Aber dazu mehr in Part 2, jetzt kommt erstmal etwas Code (es gibt auch das gesammelte Packet weiter unten):
Hier mal unsere config.php Datei, wo alle wichtigen Zugangsdaten für die MySQL DB gespeichert sind.
CREATE TABLE `data` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`keyword` varchar(255) NOT NULL,
`desc` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`pr` int(11) NOT NULL default 5,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Das ist unsere Tabelle data, wo wir die Metadaten der Webseiten speichern werden.
Dies erledigt folgender Script.
add.php speichert die Metadaten einer Webseite in der Datenbank, wenn der title und description tag
vorhanden ist. Sollte die Url in der Datenbank bereits vorhanden sein, wird der vorhandene Datensatz aktualisiert.
Nun brauchen wir noch einen Script der die Daten durchsucht und im Idealfall auch ein Ergebnis ausspuckt.
(Beachte das dieser Script über ajax aufgerufen wird.)
result.php schaut in der Datenbank, ob der übergebene Parameter $_POST[search] vorhanden ist und sortiert die Ergebnisse nach dem Feld pr.
In diesem Feld speichern wir das Userranking.
Nun benötigen wir noch eine Seite, die es dem Benutzer erlaubt die Suchanfragen einzugeben:
index.php ist im wesentlichen dazu da, dem Benutzer ein Eingabefeld zu zeigen, von wo er die Suchanfrage
starten kann. Darüber hinaus übernimmt der Script auch das Uservoteing und somit ist er auch Bestandteil des Rankings.
Zu guter Letzt noch die ajax.js Datei, sie übergibt im Hintergund die eingegebenen Daten aus dem Textfeld der result.php Datei.
Tatatata! Fertig ist unsere Suchmaschine mit der beliebten usergenerierten Sortierung!
Gesamter Script: Downloaden | Demo
Licence GPL 2
In Part 2 werde ich noch näher darauf eingehen, wie man die Daten automatisiert in die Datenbank
schreibt, und wie man eine "Meinten Sie .." Funktion implementiert.
Ausserm werde ich das Thema SEO aus einem eher technischen Gesichtspunkt beleuchten und
versuchen die Suchergebnisse zu optimieren.
Ich hoffe euch hat der kleine Exkurs in die Welt der Suchmaschinen gefallen, wenn ja
freue ich mich immer über ein Kommentar, wenn nein siehe wenn ja. :)
Best Regards
Andreas
Quellen
http://yacy.net/
http://larbin.sourceforge.net/index-eng.html
http://www.gnu.org/software/wget/