[QUIZ#11] _Grubi (PHP)

_Grubi

Erfahrenes Mitglied
Dies ist die Lösung zu Teil 1. Teil 2 folgt evt. noch.

PHP:
<?php
require_once('caeser.class.php');

$input = 'xfcu leu jzcsvi czvs zty jvyi,
bree\'j rlty nfyc xvsirltyve,
yrvkk zty ufty vze xreqvj dvvi,
dzty urivze ql krltyve.';

$caeser = new Caesar();
$ret = $caeser->Encipher($input, 9);
echo $ret;
?>

Ausgabe:
Code:
GOLD UND SILBER LIEB ICH SEHR,
KANN'S AUCH WOHL GEBRAUCHEN,
HAETT ICH DOCH EIN GANZES MEER,
MICH DAREIN ZU TAUCHEN.

caeser.class.php
PHP:
<?php
class Caesar
{
	private $defaultKey;
	
	function __construct($key = null)
	{
		$this->SetKey($key);
	}
	
	// Setz den zu nutzenden Standard-Key
	public function SetKey($key)
	{
		$this->defaultKey = $this->CheckKey($key, false);
	}
	
	// Versucht den passenden Key zu finden und dechiffriert den Text
	public function FindKeyAndDecipher($enciphered)
	{
		$key = $this->FindKey($enciphered);
		
		$deciphered = $this->Decipher($enciphered, $key);
		
		return $deciphered;
	}
	
	// dechiffriert den Text
	public function Decipher($enciphered, $key = null)
	{
		// Überprüft den Key auf Gültigkeit
		$key = $this->CheckKey($key);
		
		// Rotiert die Buchstaben A-Z anhand des Keys
		$abc = $this->GetRotatedAlphabet($key, false);
		
		$deciphered = '';
		$len = strlen($enciphered);
		
		// Geht alle Zeichen durch und verschiebt kleingeschriebene Buchstaben an die richtige Position
		// Es wurden Kleinbuchstaben gewählt, da chiffrierte Texte durchgehend in Kleinbuchstaben vorliegen!
		// Als Rückgabe erhält man einen durchgehend großgeschriebenen Text!
		for($i = 0; $i < $len; $i++)
		{
			$deciphered .= ( ctype_lower($enciphered{$i}) ? $abc[$enciphered{$i}] : $enciphered{$i} );
		}
		
		return $deciphered;
	}
	
	public function Encipher($str, $key)
	{
		// Überprüft den Key auf Gültigkeit
		$key = $this->CheckKey($key);
		
		// Rotiert die Buchstaben A-Z anhand des Keys
		$abc = $this->GetRotatedAlphabet($key);
		
		$enciphered = '';
		$len = strlen($str);
				
		// Geht alle Zeichen durch und verschiebt großgeschriebenen Buchstaben an die richtige Position
		// Es wurden Großbuchstaben gewählt, da nicht chiffrierte Texte durchgehend in Großbuchstaben vorliegen!
		// Als Rückgabe erhält man einen durchgehend kleingeschriebenen Text!
		for($i = 0; $i < $len; $i++)
		{
			$enciphered .= ( ctype_upper($str{$i}) ? $abc[$str{$i}] : $str{$i} );
		}
		
		return $enciphered;
	}

	// Rotiert das Alphabet anhand dem key
	// Je nachdem, ob $encipher auf true oder false steht, wird das Alphabet in den Groß- und Kleinbuchstaben getauscht (Key <-> Value).
	function GetRotatedAlphabet($key, $encipher = true)
	{
		$in = 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ';
		$out = array();
		
		for($i = 0; $i <= 25; $i++)
		{
			$out[strtolower($in{$i})] = $in{$i+$key};
		}
		
		return $encipher ? array_flip($out) : $out ;
	}
	
	// Versucht den passenden Key zu finden.
	// Vorgehensweise: Alle Buchstaben zählen. Die Buchstaben, der Buchstabe, der am Häufigsten vorkommt
	//				   wird als "e" angenommen. Damit berechnet man dann die Verschiebung!
	private function FindKey($enciphered)
	{
		$encipheredCleared = preg_replace("#[^a-z]#Uis", "", $enciphered);
		
		$max = 0;
		$max_c = 0;
		
		//$same = 0;
		
		foreach (count_chars($encipheredCleared, 1) as $ord => $cnt) 
		{
			if($max < $cnt)
			{
				$max = $cnt;
				$max_c = $ord;
			}
			/*elseif($max == $cnt)
			{
				$same++;
			}*/
		}

		return 5 + (ord('z')-$max_c); // 5 -> (ord('e')-96)
	}
	
	// Überprüft den Key und wirft falls nötig eine Exception!
	private function CheckKey($key, $checkDefault = true)
	{
		if($key == null && $checkDefault)
		{
			if($this->defaultkey == null)
			{
				throw new Exception('Es wurde kein Key angegeben! Setzte einen Standard Key oder gib einen beim Funktionsaufruf an!');
			}
			else
			{
				$key = $this->defaultKey;
			}
		}
		elseif( $key != null && ( $key < 1 || $key > 26) )
		{
			throw new Exception('Der Key muss sich im Bereich 1 <= key <= 26!');
		}
		
		return $key;
	}
	
	
	
}
?>
 
Habe nun auch den 2. Teil fertigstellen können.

Die Datei von Matthias kann ich ohne Probleme umwandeln, bei den Dateien, die OnlyFoo noch hinzugefügt hat, funktioniert es leider nicht, konnte aber auch keinen Fehler feststellen. Ich probiere morgen noch mit verschiedenen Schlüsselpaaren rum.

Im Anhang befinden sich die Source- und Binärdateien (diesesmal in C++).

Die Dateien PacketUtility.h/cpp stammen aus einem meiner Projekte und sind daher noch nicht extra kommentiert. Der Rest dafür schon.

Kompiliert wurde mit MinGW g++ unter WinXP Pro SP3


€dit: Daheim sind mir mit VC++ noch ein paar Fehler aufgefallen. Ich werde das morgen unter g++ mit den Änderungen nochmal testen und dann hier updaten.

€dit2:
Neuere Datei hochgeladen. Wieder mit g++ kompiliert.
 

Anhänge

  • Affine.zip
    235,4 KB · Aufrufe: 22
Zuletzt bearbeitet:
Zurück