Rot13-Codierung/Decodierung


Ein sehr verbreitetes Verfahren ein Dokument für "normale" Menschen auf den ersten Blick unlesbar zu machen ist das Rot13-Verfahren.
Dieses Verfahren (eine spezielle Variante der Caesar-Verschluesselung) und beruht auf einer monolinearen Substitution, d.h. ein Buchstabe des Alphabets wird durch genau einen anderen ersetzt.
Beim Rot13-Verfahren ist dieser immer genau der 13. darauffolgende Buchstabe im Alphabet (wenn das Ende erreicht ist fängt man wieder beim 'a' an zu zählen), was dieses Verfahren allerdings leicht zu knacken macht. Es eignet sich daher nicht zur Verschlüsselung vertraulicher Daten, sondern nur zur "Verschleierung".
Das besondere am Rot13-Algorithmus ist, das man um einen verschluesselten Text zu entschluesseln ihn nur ein zweites Mal anwenden muss, da es egal ist, ob man 13 Buchstaben vorwärts oder rückwärts zählt.
 


Hier ist also mal das Headerfile rot13.h:

 
 
 
/************************************************************* 
* Baitronic Rot-13 En/Decoder  
* Please read the terms and conditions of the  
* GNU-Public License			    www.baitronic.de 
*							  
* Usage: 	encrypt13 (letter1): 
* 		returns the corresponding letter which is given  
* 		by the rot13 permutation. (letter on the 13th  
* 		place after the given letter). 
* 				 
* 				 
*************************************************************/ 
 
char encrypt13(char letter1){ 
 
	char template[52], template_big[52]; 
	char *templ, *templ_big; 
	int i; 
 
/* Template für Alphabet vorbereiten*/ 
 
strcpy(template,    "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); 
strcpy(template_big,"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"); 
 
/*Zeiger initialisieren, auf 1. Element setzen*/ 
 
templ=template; 
templ_big=template_big; 
 
/*Pointer der Templates verschieben, bis Buchstaben übereinstimmen, dann 
 * 13 Buchstaben weiterschieben und pointer zurücksetzen 
 * */ 
 
i=1; 
for(i=1; i<=27;i++){ 
	if(letter1==*templ){ 
			templ+=13;         /*Kleinbuchstabe*/ 
			return(*templ); 
			templ-=13;         /*ausgangsstellung*/	 
	} 
	if(letter1==*templ_big){           /*Grossbuchstabe*/ 
			templ_big+=13; 
			return(*templ_big); 
			templ_big-=13;	   /*ausgangsstellung*/	 
	} 
   templ++; 
   templ_big++; 
  } 
  return ('0'); /*kein Buchstabe, nicht in Templates*/ 
} 
 
 

Um das Vorgehen kurz zu beschreiben: Ich habe zwei Templates gebaut eines für Groß- und eins für Kleinbuchstaben. Ich setze einen Pointer auf den Buchstaben den ich verschlüsseln will und schiebe ihn 13 Stellen weiter. (Damit ich bei 'Z' auch noch 13 Stellen weiterschieben kann habe ich einfach das Alphabet zweimal in meinem Template aufgenommen). Dann gebe ich den Buchstaben zurück auf den der Pointer zeigt und setze den Pointer wieder zurück.
Falls es kein Buchstabe ist, wird '0' zurückgegeben, ansonsten der verschlüsselte Buchstabe.
Wundert euch übrigens nicht über meine kommentare, ich bin was die Sprache angeht herrlich inkonsequent. Hier hab ich auch auf englisch angefangen und andere Kommentare auf Deutsch geschrieben. Naja, jeder hat so seine Macken ;-)

Dann hab ich hier noch ein kleines Programm geschrieben, das dieses Headerfile benutzt. Dieses stell ich hier mal dazu, kommentiere es aber nicht weiter:

 
 
##include < stdio.h > 
##include < string.h > 
##include "rot13.h" 
 
main(){ 
 
char text[100], text2[100];  
 
/*verschlüsselter Text wird ausgegeben und int text2 
 * gespeichert 
 */ 
 
char *textptr; 
char a, ctrl, b; 
int i, firsttime=0; 
 
 
void crypt(char *text3){ 
  i=0; 
  if(!text3){ 				/*Wenn kein Text übergeben wird*/ 
	  system("clear"); 
	  printf("Text to encrypt/decrypt: \n\n"); 
	  gets(text); 
	  system("clear"); 
	  printf("encrypted/decrypted text: \n\n"); 
	  textptr=text; 
  }   
  else {  				/*übergebenen Text verschlüsseln*/ 
	  textptr=text3; 
	  system("clear"); 
	  printf("encrypted/decrypted text: \n\n"); 
  } 
 
  while(i < strlen(text)){ 
 
    a=encrypt13(*textptr);	 
 
    if (a !='0'){ 
		putchar(a); 
		text2[i]=a; 
	} 
    else { 
		putchar(*textptr); 
		text2[i]=*textptr; 
	} 
    textptr++; 
    i++; 
  } 
  printf("\n\n"); 
} 
 
 
char ask(){ 
  if(firsttime==1){ 
    printf("NewText/Again/Quit? (n/a/enter): "); 
    gets(&ctrl); 
    system("clear"); 
    return(ctrl); 
  } 
  else{ 
    firsttime=1; 
    return('n'); 
  } 
} 
 
 
system("clear"); 
 
while(b=ask()){ 
   if(b=='n') crypt('\0'); /*Bei neuem Text NullTerminator übergeben*/ 
   if(b=='a') crypt(text2);/*Bei again pointer aufgespeicherten Text */ 
} 
system(0); 
 
 
} 
 

Sollte übrigens jemand eine schnellere/bessere Methode des Rot13-Algorithmus kennen/programmieren würde ich ihn bitten mir seinen Quelltext zu zeigen, ich weiß nicht inwiefern meine Umsetzung Performance bietet.

Hier sind auch noch die Files zum Runterladen:
rot13.h
rot13.c
 


Um keine Vorschläge vorzuenthalten: Volkard hat mir in einer Mail einen anderen Vorschlag gemacht, der vermutlich schneller funktioniert. Hier ist einfach mal den Inhalt der Mail:

Hello baitronic,

Auf http://www.linuxhilfen.org/c/c_aufsteiger_rot.html schreibste:
>Sollte übrigens jemand eine schnellere/bessere Methode des
>Rot13-Algorithmus kennen/programmieren würde ich ihn bitten mir
>seinen Quelltext zu zeigen, ich weiß nicht inwiefern meine Umsetzung
>Performance bietet.
Öhm, jo, es geht schon viel schneller.
Hoffe, es reicht Dir, wenn ich meinen Vorschlag nur mal so
hinschreibe, ohne zu testen.

unsigned char encrypt13(unsigned char ch)//unsigned erklär ich gleich
{
   static char* table=makeTable();//damits nur einmal pro programmlauf
   //passieren muß nehm ich static
   return table[ch];//deswegen unsigned, weil ich für den arrayzugriff
   //keine negativen zahlen haben mag
}
char* makeTable()
{
   int i,j;
   static char table[256];//static, damit der speicher am leben bleibt
   for(i=0;i<256;++i)
      table[i]=i;
   //so, ne table, die nix tut, ist schonmal fertig.
   //und nun die Buchstaben
   for(i=0;i<13;++i)
   {
      table['a'+i]='n'+i;//aus a wird n, aus b wird m...
      table['n'+i]='a'+i;//und umgekehrt
      table['A'+i]='N'+i;//Grossbuchstaben dürfen auch mitspielen
      table['N'+i]='A'+i;
   }
   return table;
}


-- 
Best regards,
 volkard                          mailto:volkard@marvinswelt.de
Autor: Baitronic