URL Shortener – Quick & Dirty

Radio Charivari nutzt es nicht.
Andere setzen aufs Framejacking.
Aber es kann doch nicht so schwer sein, einen eigenen URL Verkürzer zu basteln?

Ist es ja auch nicht.
In der Quick&Dirty Reihe gibts von mir heute einen Verkürzer.
Was brauchen wir dazu?

  • Webserver, Apache
  • Perl
  • Domaine

Ok, die Domaine ist klar, irgendwas Kurzes.
Als Ziel hab ich mir gesetzt, den schmutzigsten und rudimentärsten Shortener zu skripten, den man sich vorstellen kann.
Sicherheitsfeatures?
Nö, wozu auch, kostet nur Codezeilen:))
Datenbank?
Mit so Extras geben wir uns nicht ab, eine Datei tuts auch.

Stürzen wir uns also gleich ins Geschehen..

#!/usr/bin/perl

Genauso muss ein gutes Skript anfangen.

use strict;
use CGI;

Wow, doch ein Package? Du hast doch gesagt, wir machen was ganz Rudimentäres?
Ja, das machen wir auch. Aber mir erleichtert das Skript die Interaktion. Und außerdem hab ich keinen Rechner gefunden, auf dem das Packet nicht installiert wäre.
Ist auch das Einzige..versprochen!

my %database;
my %revdatabase;
my $save = "c:\\tmp\\url";
my $cgi = CGI->new;

2 Hashes aufsetzen, die Datei festlegen, in der wir unsere URLs reinschreiben, und ein Webobjekt erstellen.

%database=get_file_database($save);

Denn wollen wir mal unsere Datenbank auch in den Hash ablegen:

sub get_file_database{
my $file = shift;
open(FILE,"< $file"); my %datbase=(); while(FILE){ if($_=~ /^(\d+)\s+(.+)/){ $datbase{$1}=$2; }} close(FILE); return %datbase;}

Na, wie haben wir unsere URL Datei aufgebaut?
Richtig: "Index Leerzeichen URL"
Wer jetzt zu weinen beginnt, hat einfach keine starken Nerven.
Weiter im Hauptcode.
Hier beginnt nun eine if-Klausel.
Die ich von hinten aufzäumen möchte:

}else{
print $cgi->start_html(-title=>'My Urlizer');
print $cgi->header('text/html'), $cgi->h1('Enter URL to shorten');
formular($cgi);
print $cgi->end_html;
}

Ist recht simpel, Titel wird gesetzt und ein Formular erstellt, dort kann man die URL eintragen.
Hab ich von Selfhtml kopiert, ist somit nicht weiter lustig.
Jetzt aber zurück zur Bedingung. Hier steht noch einiges aus.

if($cgi->param('absenden')){

Ah, aus dem Formularfeld wird absenden weitergegeben.
Also vermutlich, wenn wir eine URL zum Kürzen haben..
Genau:

print $cgi->header;
print $cgi->start_html(-title=>'My Urlizer');

Zunächst der Header..*gähn*

my $idz = scalar keys %database;
$idz += 1;
%revdatabase= reverse %database;

Ha!
die Länge unserer Datenbank plus 1 setzen..und die Datenbank umdrehen.
weshalb die Datenbank umdrehen?

print $cgi->h3('Your URL is');
if($revdatabase{$cgi->param('url')}){

eben deshalb. Ich will gucken, ob ich die URL schonmal gespeichert hab, dann muss ich das nicht nochmals aufnehmen.
Und jetzt kommt der kontroverse Teil..

print $cgi->p(encode_36($revdatabase{$cgi->param('url')}));
# print $cgi->p($revdatabase{$cgi->param('url')});
}else{
write_file_database($idz, $cgi->param('url'), $save);
print $cgi->p(encode_36($idz));
# print $cgi->p($idz);
}

Du hast doch gesagt, das ding soll einfach sein!!1!einself
Ja, ich gebs zu, aber ich hatte zu einem frühen Zeitpunkt schon mit der base36 encodierung begonnen. also, weshalb sollte ich das nicht nehmen?
🙂
Und wer auf reiner Zahlenbasis arbeiten will, dann enthält die verkürzte URL eben im hinteren Teil nur Zahlen, der soll die kommentierten Zeilen auskommentieren und die darüber kommentieren.
Zufrieden?

print $cgi->p('Short another URL?');
formular($cgi)

Und noch ans Ende das Formular geklebt, vielleicht will man noch ne URL kürzen.
Jetzt aber kleiner Sprung zur Dateireinschreibefunktion:

sub write_file_database{
my $id = shift;
my $url = shift;
my $file = shift;
open(FILE,">>$file") or open(FILE,">$file");
print FILE "$id\t$url\n";
close(FILE);}

Wer vorhin noch nicht geweint hat, wird spätestens jetzt zusammenbrechen.
Nicht nur schreiben wir in die Datei nur Zahl und URL rein.
Nein, viel schlimmer.
Wenn ich was an eine Datei nicht anhängen kann.überschreib ich die Datei?
Genau, das ist Dirty.
So erzeuge ich schnell, ohne Touch oder ähnliches eine Datei.
:))
Und vernichte sie im Ernstfall auch wieder.
Genau, deshalb sollte man auch keine URL shortener verwenden!
😉
Noch dabei?
Taschentücher vollgeweint?
Dann scheut euch mal die base36 Funktionen an, zunächst aus einer Zahl, z.B. 100, eine Base36, z.B. 2S, Zeichenkette erstellen:

sub encode_36{
my $n = shift;
my $s="";
return(0) if $n == 0;
while ( $n ) {
my $v = $n % 36;
if($v < = 9) { $s .= $v; } else { $s .= chr(ord("A") -10 + $v); } $n = int $n / 36; } return "0" x ( 0 - length($s)) . reverse($s);}

Und natürlich wieder rückwandeln, in eine Zahl:

sub decode_36 {
my ($t, $i) = 0;
foreach(split //, reverse uc shift) {
$_ = ord($_) - ord("A") +10 unless /\d/;
$t += $_ * (36 ** $i++);
}
return $t;}

Ok, das ganze hab ich aus Math::Base36 geklaut.
Und etwas modifiziert.
ord(„A“) hinzugefügt..denn nicht auf jedem System ist „A“ 65 im ASCII Code.
Aber wie ich festgestellt habe, kann man natürlich auch diesen Base36 Quatsch weglassen.
Werden die kurzen URLs eben nicht so fancy und sophisticated.
Wars das schon?
Natürlich nicht, denn eine kurze URL muss bei Ankunft weitergeleitet werden:

}elsif($cgi->param('red')){
redirect($cgi->param('red'))

Kurz und schmerzlos:

sub redirect{
my $short = shift;
$short = decode_36($short);#
my $url = $database{$short};
$cgi->redirect($url);}

Bei einer reinen Zahlenshorturldienstleistung muss man natürlich die 3. Zeile auskommentieren.

Das wärs eigentlich gewesen fehlt nur noch die Apache Konfiguration:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ shoturl.pl?red=$1 [L]

Hab ich so ausm Netz und nicht überprüft.
Wozu auch, klappt sicherlich schon.

Wie Ihr seht, ist das Skript so Q&D, dass ich nichtmal den Dateinamen shoturl.pl angepasst hab.

Schmähungen, Drohbriefe und sonstige Späße könnt ihr wie immer in den Kommentaren hinterlassen

Dieser Beitrag wurde unter Initializing /dev/chaos veröffentlicht. Setze ein Lesezeichen auf den Permalink.

2 Kommentare zu URL Shortener – Quick & Dirty

  1. isnochys sagt:

    tl;dr:
    longURL => shortURL
    shortURL =>redirect(longURL)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.