textdatei verschlüsseln



  • hallo,
    ich hab folgende Aufgabe bekommen:
    Schreiben Sie ein Programm zum Verschlüsseln bzw. Entschlüsseln von
    Textdateien. Die Verschlüsselung wird erreicht, indem jeder Buchstabe im
    Bereich a-z und A-Z um einen "geheimen" Wert verschoben wird. Das heißt zum
    Beispiel für eine Verschiebung um 5 für das Wort "Atom" eine Verschlüsselung
    nach "Fytr". Die Verschiebung ist zyklisch, d.h. z um den Wert 1 verschoben
    ergibt a. Das Programm wird mit einem Parameter -v (zum Verschlüsseln) oder -e
    (zum Entschlüsseln) und dem Namen der Textdatei parametrisiert. Der "geheime"
    Wert der Verschiebung ist als Konstante fest in das Programm zu integrieren. Die
    Zieldatei hat den gleichen Namen wie die Originaldatei, die zu löschen ist.

    wobei ich da jetzt recht viele Probleme hätte:
    * zum einen wie liest man zeichen einzeln aus ohne das man weiß wie lang die datei ist(habs jetzt mit getchar gemacht..kA ob das so geht)
    * zum zweiten wie kann ich es abfangen das die zeichen nicht in einen ungültigen berecih verschoben werden also =! a-z && A-Z
    * und weiterhin wie kann ich ein einzelnes zeichen in einer datei ändern ohne alle vorhandenen zu überschreiben(weil mit "w" ja alles gelöscht und dann etwas neu gespeichert wird und mit "a" wiederum ja nur etwas an die alte datei angehängt wird

    hab schon nen bissl was versucht zu progn wobei ich da nicht sonderlich weit kahm und auch so manchen aufgabenpunkt nicht berücksichtigt habe da ich bei dennen wie schon gesagt noch keine Ahnung hatte wie's geht 😞

    #include <stdio.h>
    #include <conio.h>
    
    int main (int argc, char *argv[])  {
    
    File *datei1
    datei1 = fopen (argv[1], "r")
    File *datei2
    datei2 = fopen (argv[2], "a")
    int asci1, asci2;
    char zeichen, zeichenV;
    int konstante = 5;
    
    if(datei1 =! NULL){
    	do{
    		zeichen=getchar()
    			if(zeichen =! NULL){
    				asci1 = zeichen;
    				asci2= asci1+konstante;
    
    				zeichenV = asci2;
    
    				fprintf(datei2, "%c", zeichenV)
    
    		}while(zeichen =! NULL)
    	}else{
    		printf("%s nicht vorhanden", datei1);
    	}
    

    Würde mich über par hilfestellungen sehr freuen.



  • also du kannst einzelne zeiche z.B. mit fscanf("%c",....) einlesen oder eben mit gechar
    damit die zeiche nicht in einen unmöglichen bereich kommen musste du eine if anweisung einbuaen also wenn z.B

    if(charText>256){charText=0;}
    

    und letztens du könntest eine 2.Datei erstellen und danach die alte löschen:D
    hoffe es hilft dir:D



  • man könnte das auch schön über eine lookup table lösen, das füllen der tabelle fehlt noch aber denke das prinzip wird klar 😉 vorteil ist dass du nicht jedes zeichen um ein festes offset verschiebst.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *encode(char *str,char *encodeLookup){
    	int l = strlen(str);
    	char *ret = malloc(l*sizeof(char));
    	if(ret!=0){
    		while(l--){
    			ret[l] = encodeLookup[(unsigned char)str[l]];
    		}
    	}
    	return ret;
    }
    
    char *decode(char *str,char decodeLookup[]){
    	int l = strlen(str);
    	char *ret = malloc(l*sizeof(char));
    	if(ret!=0){
    		while(l--){
    			ret[l] = decodeLookup[(unsigned char)str[l]];
    		}
    	}
    	return ret;
    }
    
    int main(void) {
    	char encodeTable[256];
    	char decodeTable[256];
    
    	encodeTable[' '] = '_';
    	encodeTable['H'] = 'W';
    	encodeTable['e'] = 'o';
    	encodeTable['l'] = 'r';
    	encodeTable['o'] = 'd';
    	encodeTable['W'] = 'x';
    	encodeTable['r'] = 'l';
    	encodeTable['d'] = 'k';
    
    	decodeTable['_'] = ' ';
    	decodeTable['W'] = 'H';
    	decodeTable['o'] = 'e';
    	decodeTable['r'] = 'l';
    	decodeTable['d'] = 'o';
    	decodeTable['x'] = 'W';
    	decodeTable['l'] = 'r';
    	decodeTable['k'] = 'd';
    
    	char *text = "Hello World";
    	printf("Input:   %s\n",text);
    	char *buffer = encode(text,encodeTable);
    	printf("Encoded: %s\n",buffer);
    	buffer = decode(buffer,decodeTable);
    	printf("Decoded: %s\n",buffer);
    
    	return 0;
    }
    

    lg lolo



  • Das Verschieben würde ich irgendwie so machen:

    verschlüsseltesZeichen = ((zuVerschlüsselndesZeichen>='a'&&zuVerschlüsselndesZeichen<='z') //a-z
        ||(zuVerschlüsselndesZeichen>='A'&&zuVerschlüsselndesZeichen<='Z'))? //A-Z
        (zuVerschlüsselndesZeichen-'a'+geheimeZahl)%26+'a': //a-z||A-Z-Zeichen werden bearbeitet
        zuVerschlüsselndesZeichen; //andere Zeichen bleiben gleich
    

    Entschlüsseln geht genauso bloß halt -geheimeZahl.
    Die Datei kannst du einfach komplett als String einlesen, dann zeichenweise verschlüsseln und den String speichern. Ich würde nicht zeichenweise die Datei lesen.
    Eine Datei einlesen ist ein übliches "Problem", ich habe da meine Standardfunktion:

    char *readFile(const char *filename){
    	//code heavily changed from http://www.cplusplus.com/reference/clibrary/cstdio/fread/
    	FILE *file = fopen(filename, "rb");
    	if (!file) return 0;
    	//get file size
    	fseek(file, 0, SEEK_END);
    	size_t filesize = ftell(file); //files >4GB?
    	rewind(file);
    	//get memory to contain the whole file
    	char *buffer = (char*)malloc(filesize+1);
    	if (!buffer) return 0;
    	//read file
    	if (fread(buffer, 1, filesize+1, file)!=filesize){
    		free(buffer);
    		fclose(file);
    		return 0;
    	}
    	//clean up
    	fclose(file);
    	buffer[filesize] = '\0';
    	return buffer;
    }
    

    Vergiss nicht zu kucken ob readFile eine 0 zurückgegeben hat in welchem Fall das Dateilesen fehlgeschlagen ist.
    Wenn du die Datei dann mit fopen(argv[2], "w") öffnest wird ihr Inhalt automatisch gelöscht und du kannst den verschlüsselten Text per fwrite oder fprintf dort hineinschreiben.

    argc ist die Anzahl der übergebenen Parameter und sollte 3 sein. Der erste Parameter (argv[0]) ist der Pfad zu deinem Programm, der zweite (argv[1]) sollte "-v" oder "-e" sein und der dritte (argv[2]) der Dateiname. Wenn argc nicht 3 ist kannst du dich mit einem "falsche Parameteranzahl: benutzen Sie [-v|-e] [Dateiname]" verabschieden. Wenn argv[1] ungleich "-v" und "-e" ist gibst du auch einen entsprechenden Fehler aus. Strings vergleichen mit strcmp, nicht mit ==.

    Nun solltest du es hinkriegen, fehlt eigentlich nur noch die for-Schleife die über Buffer iteriert und die Zeichen bearbeitet.



  • reicht natürlich auch so, langsam schäm ich mich dass ich hier immer so ne grüze post 😕

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *translate(char *str,char *lookupTable){
    	int l = strlen(str);
    	char *ret = malloc(l*sizeof(char));
    	if(ret!=0){
    		while(l--){
    			ret[l] = lookupTable[(unsigned char)str[l]];
    		}
    	}
    	return ret;
    }
    
    int main(void) {
    	char encodeTable[256];
    	char decodeTable[256];
    
    	encodeTable[' '] = '_';
    	encodeTable['H'] = 'W';
    	encodeTable['e'] = 'o';
    	encodeTable['l'] = 'r';
    	encodeTable['o'] = 'd';
    	encodeTable['W'] = 'x';
    	encodeTable['r'] = 'l';
    	encodeTable['d'] = 'k';
    
    	decodeTable['_'] = ' ';
    	decodeTable['W'] = 'H';
    	decodeTable['o'] = 'e';
    	decodeTable['r'] = 'l';
    	decodeTable['d'] = 'o';
    	decodeTable['x'] = 'W';
    	decodeTable['l'] = 'r';
    	decodeTable['k'] = 'd';
    
    	char *text = "Hello World";
    	printf("Input:   %s\n",text);
    	char *buffer = translate(text,encodeTable);
    	printf("Encoded: %s\n",buffer);
    	buffer = translate(buffer,decodeTable);
    	printf("Decoded: %s\n",buffer);
    
    	return 0;
    }
    


  • noobLolo schrieb:

    reicht natürlich auch so, langsam schäm ich mich dass ich hier immer so ne grüze post 😕

    Tja, dafür kann man sich registieren und seine Grütze wieder löschen 😉



  • nwp2 schrieb:

    ich habe da meine Standardfunktion

    also bei größeren dateien hauts dir doch den ram um die ohren? wenn schon sowas dann mit callback auf teilstrings.

    lg lolo



  • nwp2 schrieb:

    noobLolo schrieb:

    reicht natürlich auch so, langsam schäm ich mich dass ich hier immer so ne grüze post 😕

    Tja, dafür kann man sich registieren und seine Grütze wieder löschen 😉

    noch hab ich die hoffnung dass ichs irgendwann besser mach, sollte das noch öfter vorkommen werd ich deinem vorschlag folgen. 😉



  • hab mich mal drangesetzt und nen funktionierenden ökonomischen script geschriebn er verschiebt die Buchstaben jeweils um eine Stelle:

    #include <iostream>
    
    using namespace std;
    FILE*fsrc,*ftar;
    string s;
    int main()
    {
        int choice;
        cout<<"Verschluesseln: 1\nEntschluesseln: 2\n";
        cin>>choice;
        if(choice==1)
        {
    
        cout<<"Dateiname:";
        cin>>s;
        fsrc=fopen(s.data(),"r+");
        s.append(".key");
        ftar=fopen(s.data(),"w+");
        cout<<"\n";
        char Buchstabe;
        while(1)
        {
        fscanf(fsrc,"%c",&Buchstabe);
        if((++Buchstabe)>254)
        Buchstabe=0;
        if(feof(fsrc))
        break;
        fprintf(ftar,"%c",Buchstabe);
        }
        fclose(fsrc);fclose(ftar);
        }
        else if(choice==2)
        {
            cout<<"Dateiname:";
            cin>>s;
            fsrc=fopen(s.data(),"r+");
            cout<<"\n";
            s.erase(s.length()-4,4);
            ftar=fopen(s.data(),"w+");
            char Buchstabe;
    
            while(1)
            {
                fscanf(fsrc,"%c",&Buchstabe);
                if((--Buchstabe)<1)
                Buchstabe=255;
                if(feof(fsrc))
                break;
                fprintf(ftar,"%c",Buchstabe);
            }
            fclose(fsrc);fclose(ftar);
        }
        else
        cout<<"Falsche Eingabe";
        return system("PAUSE");
    }
    

    Hoffe es hilft jemanden 😃



  • also so würds mir ganz gut gefallen, denk das braucht sich auch performance mäßig nicht verstecken, könnts ja mal eure meinung posten

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define ERR_FILE_OPEN -1
    #define ERR_FILE_WRITE -2
    #define ERR_FILE_SEEK -3
    #define ERR_FILE_CLOSE -4
    
    #define WORK_BLOCK_SIZE 8096
    
    char encodeTable[256];
    char decodeTable[256];
    
    int processFile(char *fileName,void (*callback)(char*)){
    	char buffer[WORK_BLOCK_SIZE+1];
    	int bytesRead;
    	FILE *fp = fopen(fileName, "r+");
    	if(fp==0)
    		return ERR_FILE_OPEN;
    	while(1){
    		bytesRead = fread(buffer,sizeof(char),WORK_BLOCK_SIZE,fp);
    		if(bytesRead==0)
    			break;
    		buffer[bytesRead]='\0';
    		callback(buffer);
    		if(fseek(fp, -bytesRead, SEEK_CUR)!=0)
    			return ERR_FILE_SEEK;
    		if(fwrite(buffer,sizeof(char),bytesRead,fp)!=bytesRead)
    			return ERR_FILE_WRITE;
    		if(fseek(fp, bytesRead, SEEK_CUR)!=0)
    			return ERR_FILE_SEEK;
    	}
    	if(fclose(fp)!=0)
    		return ERR_FILE_CLOSE;
    	return 1;
    }
    
    void encodeCallback(char *str){
    	int l = strlen(str);
    	while(l--){
    		str[l] = encodeTable[(unsigned char)str[l]];
    	}
    }
    void decodeCallback(char *str){
    	int l = strlen(str);
    	while(l--){
    		str[l] = decodeTable[(unsigned char)str[l]];
    	}
    }
    void printCallback(char *str){
    	printf("%s",str);
    }
    
    void setTranslationTable(){
    	encodeTable[' '] = '_';
    	encodeTable['H'] = 'W';
    	encodeTable['e'] = 'o';
    	encodeTable['l'] = 'r';
    	encodeTable['o'] = 'd';
    	encodeTable['W'] = 'x';
    	encodeTable['r'] = 'l';
    	encodeTable['d'] = 'k';
    
    	decodeTable['_'] = ' ';
    	decodeTable['W'] = 'H';
    	decodeTable['o'] = 'e';
    	decodeTable['r'] = 'l';
    	decodeTable['d'] = 'o';
    	decodeTable['x'] = 'W';
    	decodeTable['l'] = 'r';
    	decodeTable['k'] = 'd';
    }
    
    int main(void) {
    	char *fileName = "/home/matthias/Desktop/sammy.txt";
    
    	setTranslationTable();
    
    	printf("input  :");
    	processFile(fileName,printCallback);
    	processFile(fileName,encodeCallback);
    	printf("\nencoded:");
    	processFile(fileName,printCallback);
    	processFile(fileName,decodeCallback);
    	printf("\ndecoded:");
    	processFile(fileName,printCallback);
    
    	return 0;
    }
    

    lg lolo



  • arr man sollte natürlich bevor man mit return aus processFile springt die datei schließen. @nwp2 ja es wird doch mal zeit für ne anmeldung...



  • naja und den callbacks könnte man ja die string länge auch gleich mit geben dann brauchen sie die nicht immer wieder auslesen, also eine never ending story 😉



  • nwp2 schrieb:

    ...
    //get memory to contain the whole file
    char *buffer = (char*)malloc(filesize+1);
    ...
    

    malloc bitte nicht casten, gilt als schlechter stil und so, das weisste ja sicher.

    noobLolo schrieb:

    also bei größeren dateien hauts dir doch den ram um die ohren?

    ...oder wenn 'ftell' fehlschlägt. was macht 'malloc' eigentlich, wenn man ihm eine -1 vorsetzt? *fg*
    🙂



  • Ich habs noch nicht ausprobiert was bei großen Dateien passiert. Eigentlich sollte malloc fehlschlagen und alles ist schick. Und ich muss malloc casten weil C++ dumm ist und keinen impliziten cast von void * nach wasauchimmer * hat. Fürs Forum hätte ich es rausnehmen können, hab ich vergessen.



  • nwp2 schrieb:

    Und ich muss malloc casten weil C++ dumm ist und keinen impliziten cast von void * nach wasauchimmer * hat. Fürs Forum hätte ich es rausnehmen können, hab ich vergessen.

    benenn deine sources einfach mit .c als extension, bzw. stell deine IDE so ein, dass sie den C- statt cpp-compiler anwirft. casten des rückgabewertes von 'malloc' sollte man sich garnicht erst angewöhnen, finde ich.
    --> http://c-faq.com/malloc/mallocnocast.html
    🙂



  • machs doch einfach in c, dann hast den stress nicht 😃



  • Ich weiß, dass malloc casten schlecht ist. C benutzen ist aber noch schlechter, weil dann der Schwachsinn mit "Variablen müssen am Anfang des Blocks definiert sein" und "//C++-Style Kommentare nicht erlaubt" und "class not defined" anfängt. Ich habe nichmal eine IDE, weil der Aufwand Eclipse, Netbeans und Co zum laufen zu kriegen so extrem hoch ist, dass es sich für mich nicht lohnt. Im Moment benutze ich Scite + Commandline, da weiß ich wenigstens was ich tue. Für meinen selbsgebastelten Editor habe ich ein makefile gebaut, aber der Aufwand war so extrem hoch, dass es sich nicht gelohnt hat. Obwohl es schon nett ist wenn man es erstmal hat und weiß wie man es zwingen kann etwas sinnvolles zu tun.

    Edit: Das Argument von http://c-faq.com/malloc/mallocnocast.html zieht ja mal garnich, wenn malloc nicht definiert ist kriege ich das schon mit. Es ist einfach hässlich und unnötig, das ist alles.



  • Variablen nicht am Anfang und oneline-comments sind mit C99 kein Problem 🙂



  • nwp2 schrieb:

    C benutzen ist aber noch schlechter, weil dann der Schwachsinn mit "Variablen müssen am Anfang des Blocks definiert sein" und "//C++-Style Kommentare nicht erlaubt" und "class not defined" anfängt.

    du benutzt doch GCC, oder? der kann C99 und spätestens ab da kannste auch //-comments benutzen und variablen hinsetzen wo du willst. was bedeutet denn: 'class not defined'?

    nwp2 schrieb:

    Ich habe nichmal eine IDE, weil der Aufwand Eclipse, Netbeans und Co zum laufen zu kriegen so extrem hoch ist, dass es sich für mich nicht lohnt. Im Moment benutze ich Scite + Commandline, da weiß ich wenigstens was ich tue.

    heilige steinzeit! *fg* es gibt etliche C-IDEs für linux und windoofs (code-blocks, anjuta, usw). auf der kommandozeile mit manuellem makefile-gefrickel muss doch heute kein mensch mehr programmieren. *lol* (Java-IDEs für die C-programmierung würde ich aber auch nicht unbedingt bevorzugen. kann sein, dass netbeans in verbindung mit C was taugt, aber eclipse/CDT ist definitiv mist).
    🙂



  • ;fricky schrieb:

    was bedeutet denn: 'class not defined'?

    class ist die C++-Erweiterung für struct wo man es sich sparen kann das aufrufende Objekt mitzugeben und Konstruktor/Destruktor hat, was sehr der Übersicht dient.

    ;fricky schrieb:

    heilige steinzeit! *fg* es gibt etliche C-IDEs für linux und windoofs (code-blocks, anjuta, usw). auf der kommandozeile mit manuellem makefile-gefrickel muss doch heute kein mensch mehr programmieren. *lol*

    Ich habe nichts besseres QQ.
    Aber irgendwie habt ihr schon recht. Ich werde mir mal codeblocks oder so ankucken, vielleicht kriegt man es ja ohne extremen Aufwand zum laufen.
    Edit: wenn "ich" es ohne extremen Aufwand zum Laufen kriege, nicht "man". Ich habe festgestellt, dass es unglaublich talentierte Menschen gibt, die sogar Linux benutzen können.


Anmelden zum Antworten