[C++] Cesarchiffre

Moin,
ich habe folgenden Code.
Code:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;


char cryptL(char thi, int key){
	string lo = "abcdefghijklmnopqrstuvwxyz";
	int y = 0;																
	if(lo.find(thi) == string::npos){ return thi;}
	if(lo.find(thi) + key < lo.length()){			
		y = lo.find(thi) + key;
		return lo[y];
	}
	y = (lo.find(thi) + key) - lo.length(); 
	return lo[y]; 
}

char cryptH(char thi, int key){
	string lo = "ABCDEFGHIJKLMOPQRSTUVWXYZ"; 	
	int y = 0;																
	if(lo.find(thi) == string::npos){ return thi;}
	if(lo.find(thi) + key < lo.length()){			
		y = lo.find(thi) + key;
		return lo[y];
	}
	y = (lo.find(thi) + key) - lo.length(); 
	return lo[y]; 
}

int main(int argc, char* argv[]){
	string orginal = "BlaBlub";
	string crypted = orginal;
	int key = 3;
	int I = 0;
	while(I < orginal.length()){
		crypted[I] = cryptH(orginal[I], key);
		I++;
	}	
	I = 0;
	while(I < orginal.length()){
		crypted[I] = cryptL(orginal[I], key);
		I++;
	}	

	cout << crypted << endl;
}

Wie im Topic geschrieben, soll der Code nach dem Verfahren des Cesarchiffres verschlüßeln.

Leider werden nur die kleinbuchstaben verschoben, was müsste ich ändern, damit auch großbuchstaben ersetzt werden?
 
Hallo Bratack,

Du kannst das alles eigentlich in einer einzigen Funktion machen:
C++:
char crypt(char c, int key)
{
	if(!isalpha(c))
		return c;
	char upper = (c & ~0x20);
	bool isUpper = upper == c;
	upper = ((upper - 0x41 + key) % 26) + 0x41;
	return (isUpper ? upper : (upper | 0x20));
}

Folgendes Beispiel:
C++:
std::string test = "Das ist ein TestSTring-!";
std::for_each(test.begin(), test.end(),
	[](char& c) { c = crypt(c, 27); } );

ergibt dann:
"Ebt jtu fjo UftuTUsjoh-!"

Gruss
Muepe32
 
Kannst du den code mal ausführlich schreiben? Nicht diese 3er Schreibweise & vileicht noch kommentiert. Versteh deen Code hggrade nicht wirklich
 
Welchen Teil verstehst du denn nicht? Zuerst wird der Buchstabe in einen Grossbuchstaben umgewandelt. Durch den Vergleich, ob er sich geändert hat sieht man, ob es vorher ein Kleinbuchstabe war. Anschliessend wird er vom Interval [65, 90] aufs Interval [0, 26] gebracht (-0x41), der Key hinzuaddiert, dann falls er über 26 hinausgeht mit % 26 wieder korrekt ins Interval [0, 26] eingefügt und zum Schluss mit + 0x41 wieder zurück ins Interval [65, 90] übertragen.

War es nun noch vorher ein Kleinbuchstabe muss der transformierte Grossbuchstabe wieder in einen Kleinbuchstaben umgewandelt werden, ansonsten kann er einfach zurückgegeben werden.
 
Wobei die Umwandlung mit anschließendem Vergleich verschwenderisch ist, wenn man die ASCII-Tabelle zu rate zieht, kann man das richtig schön eingrenzen:

C:
int is_upper = (c >= 60 && c <= 90);
 
Die Idee ist, dass du den Buchstaben in einen Grossbuchstaben konvertierst damit du nacher grundsätzlich unabhängig davon arbeiten kannst, ob er zwischen 65 und 90 oder 97 und 112 ist.
 
Soweit so gut, ich verstehe immer noch nicht, warum man das so kompliziert machen muss. Es handelt sich um eine Single-Substitionschiffre, evtl. noch variabler Schrittweite. Warum nimmt man nicht einfach den ASCII-Wert und rechnet +1?
 
Du kannst schon den ASCII-Wert nehmen und den Schlüssel hinzufügen. Wenn du jedoch zu 'z' 2 dazu zählst entsteht dadurch 'b'. Du musst also wieder auf das entsprechende Interval abbilden. Spätestens da musst du dann die Operationen unterschiedlich machen, je nach dem, ob es ein Gross- oder ein Kleinbuchstabe ist.
 
Zurück