String verschlüsseln
-
Hallo,
ich habe als Aufgabe gekriegt, einen String wie folgt zu verschlüsseln: Zuerst den String umkehren (das ist das kleinste Problem) und danach den ASCII-Wert jedes Zeichens zu verdoppeln.
Das ist meine Verschlüsselungsfunktion:char encrypt(char* plainstring) { int stringlaenge = strlen(plainstring); char buffer[MAX_LENGTH]; strcpy(buffer, plainstring); int gegeni = 0; for(int i = stringlaenge-1; i>=0; i--) { buffer[gegeni] = (char)(2*(plainstring[i])); gegeni++; } strcpy(plainstring, buffer); return 1; }
Problem ist jetzt nur, wenn ich jetzt z.B. das Zeichen 'o' verschlüsseln will (ASCII-Code 111), dann müsste ich ja als Wert 222 rausbekommen. Aber das liegt doch außerhalb des Wertebereichs eines chars, oder?
Hier ist der Rest meines Programms, auch mit decrypt-Funktion:
#include <stdio.h> #include <string.h> #define MAX_LENGTH 21 char encrypt(char*); char decrypt(char*); char remove_newline(char*); int main() { char encryptstring[MAX_LENGTH]; printf("%c", (char)(222/2)); fgets(encryptstring, sizeof(encryptstring), stdin); remove_newline(encryptstring); encrypt(encryptstring); printf("%s\n", encryptstring); decrypt(encryptstring); printf("%s\n", encryptstring); char c; scanf("%c", &c); return 0; } char encrypt(char* plainstring) { int stringlaenge = strlen(plainstring); char buffer[MAX_LENGTH]; strcpy(buffer, plainstring); //printf("%d", stringlaenge); int gegeni = 0; for(int i = stringlaenge-1; i>=0; i--) { //printf("%d\n", (int)2*plainstring[i]); buffer[gegeni] = (char)(2*(plainstring[i])); gegeni++; } printf("%d\n", buffer[0]/2); strcpy(plainstring, buffer); return 1; } char decrypt(char* plainstring) { int stringlaenge = strlen(plainstring); char buffer[MAX_LENGTH]; printf("%d\n", (int)plainstring[0]); strcpy(buffer, plainstring); printf("%s\n", plainstring); int gegeni = 0; for(int i = stringlaenge-1; i>=0; i--) { printf("%d", (int)buffer[i]); buffer[gegeni] = plainstring[i] /2 ; gegeni++; } printf("%s\n", plainstring); strcpy(plainstring, buffer); return 1; } char remove_newline(char s[]) { int len = strlen((char*)s); if(len > 0 && s[len-1] == '\n') { s[len-1] = '\0'; return 1; } return 0; }
Ich bin für jeden Tipp und jede Hilfe dankbar! Ich verzweifle sonst noch an dieser Aufgabe
-
Faba schrieb:
Problem ist jetzt nur, wenn ich jetzt z.B. das Zeichen 'o' verschlüsseln will (ASCII-Code 111), dann müsste ich ja als Wert 222 rausbekommen. Aber das liegt doch außerhalb des Wertebereichs eines chars, oder?
Tja, dann ist eben das Verschlüsselungsverfahren nicht gut gewählt. Hast du dir das selbst ausgedacht oder ist das vorgegeben? Falls du dies als Aufgabe umsetzen musst: Nimm unsigned char und stell vor dem Verschlüsseln sicher, dass alle Werte kleiner als 128 sind. Falls du es dir selbst ausgedacht hast: Denk dir was anderes aus
.
-
SeppJ schrieb:
Faba schrieb:
Problem ist jetzt nur, wenn ich jetzt z.B. das Zeichen 'o' verschlüsseln will (ASCII-Code 111), dann müsste ich ja als Wert 222 rausbekommen. Aber das liegt doch außerhalb des Wertebereichs eines chars, oder?
Tja, dann ist eben das Verschlüsselungsverfahren nicht gut gewählt. Hast du dir das selbst ausgedacht oder ist das vorgegeben? Falls du dies als Aufgabe umsetzen musst: Nimm unsigned char und stell vor dem Verschlüsseln sicher, dass alle Werte kleiner als 128 sind. Falls du es dir selbst ausgedacht hast: Denk dir was anderes aus
.
Hallo,
danke für deine schnelle Antwort. Nein, leider ist das Verfahren nicht selbst gewählt. Sonst hätte ich das garantiert schon längst über den Haufen geworfen^^
Kann ich denn auch einen String als unsigned char deklarieren?
-
Ja
unsigned char ucBuffer[10];
wird noch relativ häufig verwendet...
Gruss Binggi
-
Hallo,
habe das Problem jetzt gelöst und wollte euch an meiner Lösung teilhaben lassen.
Zuerst war einmal das Problem, dass die Lokaleinstellung auf "C" war (umfasst nur 127 Zeichen und nicht 254). Dieses Problem war relativ einfach zu lösen.
Damit konnte ich die Zeichenketten schonmal richtig encodieren.
Beim decodieren musste ich etwas tiefer in die Materie einsteigen und mir überlegen, was mal zwei und durch zwei überhaupt bedeutet.
Wenn ich ja eine Zahl 11011110(b) habe (in Dezimal: 222) und das durch 10(b) teile dann erhalte ich ja 01101111. Eine Division durch 2 ist also nichts anderes, als dass alle Bits eins nach rechts verschoben werden und eine 0 ins hochwertigste Bit geschoben wird (rechts-shift). Ja, also den Bit-Operator >> ausprobiert und ernüchternd musste ich feststellen, dass eine 1 reingeschoben wird, weil es beim rechts-shift nicht standardisiert ist, dass eine 0 reingeschoben wird (so wie beim links-shift). Also musste ich dafür sorgen, dass dieses Bit auf 0 gesetzt wird und siehe da es klappte. Hier der Code von den wichtigsten Funktionen:char encrypt(char* plainstring) { int stringlaenge = strlen(plainstring); for(int i = 0; i < stringlaenge; i++) { // Hier findet die Codierung statt. // Verdoppeln ist nichts anderes als Bit-Shift nach links plainstring[i] = plainstring[i]<<1; } strrotate(plainstring); return 1; } char decrypt(char* plainstring) { int stringlaenge = strlen(plainstring); for(int i = 0; i < stringlaenge; i++) { // Hier findet das Decodieren statt // Halbieren ist nichts anderes als Bit-Shift nach rechts plainstring[i] = plainstring[i]>>1; // Das erste Bit von links (das 8. von rechts) muss aber mit einer 0 gefüllt werden plainstring[i]= plainstring[i] & ~(1<<7); } // String umdrehen strrotate(plainstring); return 1; } // Ermöglicht überhaupt erst, dass alle ASCII-Zeichen angezeigt werden können! // abgewandelt übernommen von: http://bytes.com/topic/c/answers/743589-print-extended-ascii-ansi-c void changelocal(const char *locale) { char *loc; if (NULL != (loc = setlocale(LC_CTYPE, NULL)) ) { printf("Lokalisierung geaendert von '%s', ", loc); } if (NULL != (loc = setlocale(LC_CTYPE, locale)) ) { printf("nach: '%s'\n", loc); } }
Das wollte ich hier nur reinstellen, falls irgendjemand vor einem ähnlichen Problem steht
achja: die Funktion changelocal braucht noch die header-Datei locale.h!
-
Faba schrieb:
und danach den ASCII-Wert jedes Zeichens zu verdoppeln.
Ah, eine gute Idee. Das erhält nämlich die 0 als Stringende.
Aber ein Problemchen ist da anzumerken: Es gibt stets zwei Zahlen, die verdoppelt die eine geben.
Ich denke mal unsigned char.
662=132
1942=132
Beim Entschlüsseln gehts irgendwann schief.Und das alles nur, weil die 2 ungeschickt ist. Nimm 3!
So, jetzt wird jede Zahl auf genau eine andere Zahl abgebildet. Keine Zweifelsfälle mehr. Und die 0 bleibt 0.
Jetzt nur noch herausfinden, wie man das entschlüsselt. Man kann ja nicht einfach durch 3 teilen, weil dann gibt es Probleme mit dem Überlauf.
Aber man kann einfach die Zahl x suchen, daß x3=1 ist.
Das findet man hiermit http://www2-fs.informatik.uni-tuebingen.de/~reinhard/krypto/German/2.2.d.html , indem man 3 und 256 eingibt.
Aha, 171 ist es. 3171=1Also kannst Du mit *3 verschlüsseln und mit *171 wieder entschlüsseln.
Gültige Schlüssel sind alle ungeraden Zahlen.
Ich würde zum Verschlüsseln die 71 nehmen, weil sie eine so bekannte Primzahl ist. Oder die 159, weil sie ungefähr 256*phi ist.
-
klingt auf jeden Fall gut die Idee
Nur ich hatte das als Aufgabe so bekommen und deshalb blieb mir da nichts anderes übrig
-
Wenn er vorhat, nur die Standard-ASCII-Zeichen von 0 bis 127 zu verwenden, geht's ja auch mit 2.
volkard schrieb:
Ich würde zum Verschlüsseln die 71 nehmen, weil sie eine so bekannte Primzahl ist. Oder die 159, weil sie ungefähr 256*phi ist.
Zum Verschlüsseln würde ich keine bekannten Zahlen nehmen