<?
/*****************************************************************
**																**
**			 		  Lempel-Ziv-Comprimator			  		**
**																**
**	 		    Scripted in PHP 5/XHTML 1.0 Strict				**
**		   			(c) 2008 by Nico Ritschel					**
**																**
**                 This file is licensed unter 					**
**     "Creative Commons Attribution 2.0 Germany"-License		**
**	     http://creativecommons.org/licenses/by/2.0/de/			**
**																**
*****************************************************************/

define("VERSION", "0.8");
define("STYLESHEET", "/style.css");
define("MINLENGTH", "5");
define("MAXLENGTH", "50000");

function uncompress($text) {
	$uncompressedtext = "";
	$dictionary = array();
	$letters = array();
	$preletters = preg_split("/(\[.*\])/Usi", $text, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
	foreach ($preletters as $number => $value) {
		if (preg_match("/\[.*\]/", $value)) {
			array_push($letters, $value);
		}
		else {
			$letterarray = str_split($value);
			$letters = array_merge($letters, $letterarray);
		}
	}
	$uncompressedtext = $letters[0];
	foreach ($letters as $number => $value) {
		if ($number != 0) {
			if (preg_match("/\[(.*)\]/", $letters[$number -1], $onlynumber)) {
				$lastletter = $dictionary[$onlynumber[1]];
			}
			else {
				$lastletter = $letters[$number -1];
			}
			if (preg_match("/\[(.*)\]/", $value, $onlynumber)) {
				if ($dictionary[$onlynumber[1] ]) {
					array_push($dictionary, $lastletter.substr($dictionary[$onlynumber[1] ], 0, 1));
					$uncompressedtext = $uncompressedtext.$dictionary[$onlynumber[1]];
				}
				else {
					$uncompressedtext = $uncompressedtext.$lastletter.substr($lastletter, 0, 1);
					array_push($dictionary, $lastletter.substr($lastletter, 0, 1));
				}
			}
			else {
				array_push($dictionary, $lastletter.$value);
				$uncompressedtext = $uncompressedtext.$value;
			}
		}
	}
	return $uncompressedtext;
}

function compress($text) {
	$compressedtext = "";
	$dictionary = array();
	$alreadyset = array();
	$letters = str_split($text);
	foreach ($letters as $number => $value) {
		if (!$alreadyset[$number]) {
			$oldentry = 0;
			$newentry = $value;
			$numbercopy = $number;
			while (in_array($newentry.$letters[$numbercopy+1], $dictionary)) {
				$oldentry = $newentry;
				$numbercopy++;
				if ($letters[$numbercopy]) {
					$alreadyset[$numbercopy] = 1;
					$newentry = $newentry.$letters[$numbercopy];
				}
				else {
					break;
				}
			}
			array_push($dictionary, $newentry.$letters[++$numbercopy]);
			if ($oldentry) {
				$compressedtext = $compressedtext."[".(array_search($newentry, $dictionary))."]";
			}
			else {
				$compressedtext = $compressedtext.$value;
			}
		}
	}
	return $compressedtext;
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="expires" content="NEVER" />
<meta name="page-topic" content="Computer/Internet" />
<meta name="author" content="Nico Ritschel" />
<meta name="copyright" content="(c) 2008 by Nico Ritschel" />

<!-- <link href="<? echo STYLESHEET; ?>" rel="stylesheet" type="text/css" /> -->
<title>Lempel-Ziv-Komprimator (v. <? echo VERSION; ?>)</title>
</head>
<body>
<?
if ((isset($_POST['compress']) OR isset($_POST['decompress'])) AND isset($_POST['text'])) {
	if (strlen($_POST['text']) < MINLENGTH || strlen($_POST['text']) > MAXLENGTH) {
		?>
<p style="color:#CC0000">Fehler: Bitte gib einen Text mit einer L&auml;nge zwischen <? echo MINLENGTH; ?> und <? echo MAXLENGTH; ?> Zeichen ein.</p> 
		<?
	}
	else {
		if (isset($_POST['compress'])) {
			if (strstr($_POST['text'], "[") || strstr($_POST['text'], "]")) {
				?>
<p style="color:#CC0000">Fehler: Der String darf die Zeichen [ und ] nicht enthalten.</p> 
				<?
			}
			else {
				$compressed = compress($_POST['text']);
				$clen = strlen($compressed);
				$uclen = strlen($_POST['text']);
				$compressed = htmlspecialchars($compressed , ENT_QUOTES);
				$compressed = addslashes($compressed);
				$_POST['text'] = htmlspecialchars($_POST['text'] , ENT_QUOTES);
				$_POST['text'] = addslashes($_POST['text']);
				?>
<p>Der komprimierte Text lautet:<br /></p>
<pre><? echo $compressed; ?></pre>
<p>(<? echo $clen; ?> Zeichen)</p>
<p>Der Originaltext lautete:<br /></p>
<pre><? echo $_POST['text'] ?></pre>
<p>(<? echo $uclen; ?> Zeichen)
</p>
<p style="margin-top:50px;">Dies ist eine Kompressionsrate von ca. <? echo 100-round(($clen/$uclen)*100, 1); ?>%</p>
				<?
			}
		}
		if (isset($_POST['decompress'])) {
			$uncompressed = uncompress($_POST['text']);
			$uclen = strlen($uncompressed);
			$clen = strlen($_POST['text']);
			$uncompressed = htmlspecialchars($uncompressed , ENT_QUOTES);
			$uncompressed = addslashes($uncompressed);
			$_POST['text'] = htmlspecialchars($_POST['text'] , ENT_QUOTES);
			$_POST['text'] = addslashes($_POST['text']);
			?>
<p>Der dekomprimierte Text lautet:<br />
<pre><? echo $uncompressed; ?></pre>
(<? echo $uclen; ?> Zeichen)
</p>
<p>Der komprimierte lautete:<br />
<pre><? echo $_POST['text'] ?></pre>
(<? echo $clen; ?> Zeichen)
</p>
			<?
		}
	}
}
else {
	?>
<p>Das folgende, in PHP geschriebene Programm komprimiert und dekomprimiert den in das Eingabefeld eingegebenen Text nach dem LZW-Verfahren. Da es aber durch das Webinterface Schwierigkeiten mit den verschiedenen Zeichens&auml;tzen gibt, werden die entsprechen Ersatzzeichen als [X] gekennzeichnet, wobei X f&uuml;r die Nummer des W&ouml;rterbucheintrages steht. Dadurch ist allerdings die Kompressionsrate sehr schlecht, weshalb dieses Programm nur zur Demonstration und nicht zur praktischen Verwendung geeignet ist.</p>
<p> Achtung: Ich rate dringend dazu, keine zu außergewöhnlichen Zeichen zu verwenden, da sonst Fehler auftreten können!</p>
    <?
}
?>
<form method="post" action="">
<p>
	<textarea rows="10" cols="50" name="text"><? echo $_POST['text']; ?></textarea>
    <br /><br />
    <input type="submit" name="compress" value="Komprimieren" />
    <input type="submit" name="decompress" value="Dekomprimieren" />
</p>
</form>
</body>
</html>