Probleme bei Enigma-Verschlüsselung

Schnelle objektorientierte, kompilierende Programmiersprache.
Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von fat-lobyte » Di Mär 27, 2012 10:05 pm

Ok, da musst du nochmal ran. Wenn man nämlich "aaaaa" statt "kmitska" eingibt, geht gar nix mehr.

Außerdem ist der Code voller Seltsamkeiten.

Code: Alles auswählen

    int NUM_begin=0, NUM_end=0;
    int b = 'a';
    NUM_begin = b;
    b = 'z';
    NUM_end = b+1;
Ein bisschen umständlich, um int "NUM_begin = 'a', NUM_end = 'z' + 1;" zu schreiben, oder?
Dabei NUM_end wird in der ersten Funktion gar nicht verwendet.

Der Fehler liegt wahrscheinlich nicht (nur?) in der dekodierfunktion, sondern überall sonst.

Hier sind ein paar dinge die mir aufgefallen sind:

Code: Alles auswählen

        static int begin=0;
        static int count=0;
        static int c = 0;
Wtf? Wieso static? Weißt du was das genau tut?

Code: Alles auswählen

            if(n==0){
                begin = NUM_begin;
            }else{
                begin = NUM_begin + count *2;
            }
count kann nur im ersten durchgang 0 sein, also verkürzt sich das zu: begin = NUM_begin + count *2; , wenn man die Rechenregeln einer Gruppe beachtet.

Code: Alles auswählen

int dif = ((int) 'a' - (int) 'A');
1. Buchstaben-Literale sind Integer (tatsächlich!) also der Cast ist unnötig.
2. Diese Zahl ist negativ. Bist du sicher dass du nicht 'A' - 'a' schreiben wolltest?

Code: Alles auswählen

for(int n=0; n<=10; n++)
Was für ne 10 ist das? Ist das aus der definition des Enigma-algorithmus? Es ist auf jeden fall eine konstante und sollte einen Namen haben.

Code: Alles auswählen

for(int a=NUM_begin; a<=NUM_end; a++)
GANZ sicher? Du hast zu NUM_end bereits +1 hinzugefügt, also würde mir "<" statt "<=" korrekter erscheinen.

Ich kenne den Algorithmus nicht, und interessiere mich auch nicht sonderlich dafür, aber ich glaube da stimmt so einiges nicht.


Wieso hat denn encode() so ne "cap" geschichte, und decode() nicht? Beim dekodieren wird encodeTableTwo[][] gar nicht verwendet.

Hier ist übrigens eine von mir ausgebesserte Version, die zumindest mal das gleiche macht wie deine:

Code: Alles auswählen

using namespace std;

int encodeTable[20][26];
int encodeTableTwo[20][26];

void ImplementEncode()
{
    int NUM_begin = 'a';
    int dif = 'a' - 'A'; // 'A' - 'a'

    int begin=0;
    int count=0;
    int c = 0;

    for(int n=0; n<=10; n++)
    {
        if(n==0){
            begin = NUM_begin;
        }else{
            begin = NUM_begin + count *2;
        }


        for(int g=0; g<=25; g++)
        {
            encodeTable[count][c] = begin;
            encodeTableTwo[count][c] = begin-dif;
            begin++;
            c++;
        }
        c = 0;
        count++;
    }
}

string encode ( string text )
{
    int NUM_begin = 'a', NUM_end = 'z' + 1;
    int dif = 'a' - 'A';

    for(std::size_t i=0; i< text.length(); i++){
        int row=0,c=0;
        bool cap=false;

        for(int a=NUM_begin; a <= NUM_end; a++)
        {
            if( (int) text[i] == a )
            {
                row=c;
                cap=false;
            }else if( (int) text[i] == a-dif)
            {
                row=c;
                cap=true;
            }
            c++;
        }

        if(!cap)
            text[i] = (char) encodeTable[i+1][row];
        else
            text[i] = (char) (encodeTableTwo[i+1][row]);

    }
    return text;
}

string decode(string text)
{
    int tmp=0;
    for(std::size_t i=0; i<text.length(); i++)
    {
        for(std::size_t n=0; n<=25; n++)
        {
            if(text[i] == (char) encodeTable[tmp+1][n])
            {
                text[i] = (char) encodeTable[0][n];
            }
        }
        
        if(tmp == 10)
            tmp=0;
        else
            tmp=i;


        tmp++;
    }
    return text;
}
Haters gonna hate, potatoes gonna potate.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Xin » Mi Mär 28, 2012 9:49 am

Kmitska hat geschrieben:Ja ich weiß, dieser Link zerstört mein Leben...
Das glaube ich nicht, das wiederholte Senden des Links zerstört höchstens meine Nerven... also halte Dich bitte daran; der Text wurde ja nicht umsonst geschrieben, sondern soll Dir und uns nutzen.
Kmitska hat geschrieben:Das Problem ist: Ich mag es nicht meine Sources zu teilen.
Das verstehe ich und das geht mir ähnlich.

Trotzdem arbeite ich mit einigen Leuten hier zusammen und denen muss ich mindestens einen Teil meiner Quellen zur Verfügung stellen, damit nicht jeder wild drauf los entwickelt.

Zusammenarbeit funktioniert nunmal so, dass alle das etwas bearbeiten können. Mit Deinen Quellen hilfst Du vielleicht anderen Anfängern. Ein Profi wird davon vermutlich die Finger lassen.

Du bist Programmieranfänger. Das ist keine Auszeichnung, es gibt unmengen an Programmieranfängern. Auf diesem Planeten laufen sogar genug Leute mit einem Informatikdiplom/-Bachelor rum, die besser programmieren können als Du. Auch die Enigma ist keine Entwicklung, die besonders kompliziert zu implementieren ist, das habe ich auch mal in Studium gemacht in einem Wahlpflichtfach. Hier ging es darum zu zeigen, dass ich Java programmieren kann. Die Enigma hat dabei keinen interessiert. Ein "Hello-World" eben.
Bei Dir geht es darum etwas zu lernen, damit Du irgendwann mal etwas schreiben kannst, was eben nicht jeder kann und wo Du dann entscheiden kannst, ob Du das als Open- oder Closed-Source betrachten willst.

Tut mir leid, aber die Enigma ist nur ein semi-professionelles Hello-World-Programm. Wenn Du es gut umsetzt zeigst Du damit, dass Du mehr kannst, als nur das Standard-"Hello World", aber bei "Hello-World" würdest Du Dich wohl auch nicht zieren, es zu veröffentlichen?!
Kmitska hat geschrieben:Ich versuch es lieber selber zu machen, was ich schon seit 2-3 Tagen versuche.
Aber das merkwürdige ist, mit cout läuft alles so wie ich will! und beim string kanns ja nicht liegen.
Du solltest Deine Quellen öfter zeigen, da gibt's noch einiges zu lernen. Darum bist Du doch auch hier, oder?
Um aus der unendlichen Masse der Anfänger zu den Semi-Pros aufzusteigen.

fat-lobyte hat schon einiges geschrieben. Was mir vornehmlich auffiel war, dass Funktionen in Headerdateien enthalten sind. Falls fat-lobyte das nicht schon kritisch anmerkte, dann tue ich das nun. Sofern Du keine Templates schreibst, haben Algorithmen in Headerdateien nichts verloren.

Beachte, was Dir fat-lobyte schreibt und Du kannst von und mit ihm schnell lernen, wie Du ein guter Entwickler wirst. Oder verbringe 2-3 Tage und löse Dein Problem selbst. So habe ich das auch gemacht - mangels Internet. Wenn Du genug Frust ertragen kannst, kannst Du so ein sehr erfahrener Entwickler werden. Aber Du solltest Deine Geduld dafür in Jahrzehnten formulieren.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Kmitska
Beiträge: 349
Registriert: Fr Sep 23, 2011 8:49 pm
Wohnort: Karlsruhe, Pforzheim

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Kmitska » Do Mär 29, 2012 8:34 pm

int dif = ((int) 'a' - (int) 'A');
1. Buchstaben-Literale sind Integer (tatsächlich!) also der Cast ist unnötig.
2. Diese Zahl ist negativ. Bist du sicher dass du nicht 'A' - 'a' schreiben wolltest?
Hast dus ausprobiert? Bei mir klappt es, damit fülle ich auch tableTwo aus! :)

Code: Alles auswählen

fat-lobyte hat schon einiges geschrieben. Was mir vornehmlich auffiel war, dass Funktionen in Headerdateien enthalten sind. Falls fat-lobyte das nicht schon kritisch anmerkte, dann tue ich das nun. Sofern Du keine Templates schreibst, haben Algorithmen in Headerdateien nichts verloren.
Gibt es da eigentlich einen Unterschied zwischen *.h und *.cpp?
Ich pack eigentlich alles in Header rein.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von cloidnerux » Do Mär 29, 2012 9:51 pm

Gibt es da eigentlich einen Unterschied zwischen *.h und *.cpp?
Ich pack eigentlich alles in Header rein.
Es sind beides normale Textdateien, aber Formal sind es zwei verschiedene Welten.
Mit *.h und *.cpp Dateien versucht man Funktionen und ihre Deklarationen zu trennen. Das bedeutet, das man die Funktionen an sich und ihren Prototypen(nur die erste Zeile, Funktionskopf) getrennt aufbewahrt, sodass man die Code-Dateien schon zu Objekt-Dateien Compilieren kann und der Compiler über die Funktionsprototypen immer noch die Funktionen kennt, sodass dann im Finalen Compilationschritt der Linker alle Objektdateien zu einer *.exe zusammenbauen kann.

Was jetzt ziemlich kompliziert klingt, ist in Wirklichkeit nicht so schlimm. Du kannst dir das Vorstellen wie ein Archiv voller Anleitungen(deine Funktionen in den *.cpp Dateien) und ein Index mit den verweisen wo welche Anleitung steht(die *.h Header Dateien).
Anstatt jedes mal die Anleitung hinzulegen, verweist man nur darauf und lässt dann im Finalen schritt, wenn man weiß welche Funktionen man braucht und welche nicht, dann die Entsprechenden Funkionen, oder Anleitungen holen.
Und es bringt auch große Probleme mit, in den Header-Dateien Funktionen definierst( also die komplette Funktion in der Header-Datei), denn zum einen wird alles unnötige mit kompiliert, zum anderen ist dann jede Hilfsfunktionen öffentlich zugreifbar und sperrt Bezeichner. hast du in Datei A.h schon eine Funktion "add(x, y)" definiert, so kannst du keine gleiche Funktion "add(x, y)" in Datei B.h definieren. Wären die Funktionen in *.cpp Dateien und nicht öffentlich, so wäre das egal.

Generell gehört es sich also, seine Funktionen in den header-Dateien zu Deklarieren und in den Code-Dateien zu definieren.
Und soweit ich weiß, kümmert sich jede Moderne IDE wie CodeLite, Code::Blocks, Visual Studio und co. darum, dass all deine eigenen *.cpp Dateien richtig compiliert werden.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Kmitska
Beiträge: 349
Registriert: Fr Sep 23, 2011 8:49 pm
Wohnort: Karlsruhe, Pforzheim

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Kmitska » Fr Mär 30, 2012 3:48 pm

Also soll ich dann die Definitionen in *.cpp packen?
Die Beispiele in meinem Buch waren auch immer in 2 Dateien, wie dus gesagt hast.
Ich fand das zu auffwändig und dachte das es nicht so viel ausmacht.

Ich hätte da noch eine Frage, wenn wir schon beim Thema (indirekt) Übersicht sind.

Was ist besser/schneller und Ressourcen freundlicher?

Wenn ich eine Funktion erstelle die dann haufenweise kram erledigt, oder eine Funktion die mit diversen Funktionen arbeitet?
Wie z. B.:

Code: Alles auswählen

lala()
{
la = lalaaaaa();
la = lalaaa2323aa();
}
oder statt externe Funktionen zu arbeiten alles darein packen?

Ich finde das mit dem Funktionen viel übersichtlicher aber weiß nun nicht was sich empfehlen lässt.

canlot
Beiträge: 393
Registriert: Di Mär 08, 2011 11:01 pm
Wohnort: NRW

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von canlot » Fr Mär 30, 2012 4:38 pm

Ressourcen freundlicher ist natürlich wenn du alles in ein Funktion reinpackst. Allerdings sehr unübersichtlich und nicht empfehlenswert. Achte stehts drauf das die Rückgabe werte stets Zeiger sind so sparst du eine Menge Rechenzeit besonders bei großen Berechnungen.
Unwissenheit ist ein Segen

Kmitska
Beiträge: 349
Registriert: Fr Sep 23, 2011 8:49 pm
Wohnort: Karlsruhe, Pforzheim

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Kmitska » Fr Mär 30, 2012 4:59 pm

Also viel mit Zeigern arbeiten und lieber Funktionen verwenden statt alles reinzuquetschen?

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von fat-lobyte » Fr Mär 30, 2012 5:16 pm

canlot hat geschrieben:Ressourcen freundlicher ist natürlich wenn du alles in ein Funktion reinpackst.
Sorry, aber das stimmt so nicht.
1) Es stimmt schon, dass man durch Inlining performance gewinnen *kann*, das kann aber auch nach hinten losgehen, wenn der Code nicht in den L1/L2 cache des Prozessors passt.

2) Das sollte man niemals selbst machen, denn der Compiler sollte das für dich übernehmen.
canlot hat geschrieben:Achte stehts drauf das die Rückgabe werte stets Zeiger sind so sparst du eine Menge Rechenzeit besonders bei großen Berechnungen.
Das war früher der richtige Weg, aber heutzutage gibt es sogenannte "RValue references", mit denen man Objekte tatsächlich verschieben kann, anstatt sie nur zu kopieren. Diese sind in allen größeren Compilern bereits unterstützt. Mehr Infos könnt ihr in diesem Thread finden: http://www.proggen.org/forum/viewtopic.php?f=21&t=4522

Ich schreibe dann eigene Funktionen, wenn:
- Du einem Stück Code einen sinnvollen Namen geben kannst. "int add_three_to_number(int)" ist ziemlich blöd, aber "int calculate_distance(int, int)" würde schon Sinn machen.
- Wenn die Funktion wiederverwendbar sein soll.
- Manche sagen, wenn deine Funktion länger als 100 Zeilen ist, sollte man sie aufspalten. Ich finde solche steifen Regeln sind ziemlich dumm, aber andererseits habe ich echt fast keine Funktion die länger als 100 Zeilen ist in meinem Code.
Kmitska hat geschrieben:Also viel mit Zeigern arbeiten und lieber Funktionen verwenden statt alles reinzuquetschen?
NEIN! Zeiger != automatischer Performancegewinn. Das ist ein Mythos, und gehört in die gleiche ecke wie "C ist schneller als C++". Das stimmt nicht.

Vom Compiler wird nämlich sowieso alles in Zeigerzugriffe übersetzt, wenns notwendig ist.

Außerdem: hast du gerade Probleme mit der Performance? Wenn nicht, dann ändere nichts. Ich predige immer: zuerst die Funktionalität herstellen, dann Geschwindigkeit MESSEN und dann erst, und auch nur wenn notwendig optimieren.

Übrigens: es ist schon gut am Anfang "Low-Level" herumzuspielen, damit man ein Gefühl dafür kriegt, wie teuer Operationen sind. Aber danach sollte man ruhig auf einer Abstrakteren Ebene (std::string, STL, ...) arbeiten.
Haters gonna hate, potatoes gonna potate.

Kmitska
Beiträge: 349
Registriert: Fr Sep 23, 2011 8:49 pm
Wohnort: Karlsruhe, Pforzheim

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Kmitska » Fr Mär 30, 2012 7:21 pm

Also:
So lange es keine Probleme gibt und das Programm ordentlich läuft brauch ich mir keine Gedanken zu machen und kann mein Code so gestalten, wie ich es will? :)

Kmitska
Beiträge: 349
Registriert: Fr Sep 23, 2011 8:49 pm
Wohnort: Karlsruhe, Pforzheim

Re: Wieso geht das nicht, Problem in Funktion

Beitrag von Kmitska » Sa Mär 31, 2012 10:54 am

Ich hätt da noch eine Frage, was ist eigentlich besser 'char' oder 'std::string'?
Ich persönlich bevorzuge std::string, da der Umgang viel einfacher ist und Ressourcen freundlich + Funktionen.
Aber was würdet ihr empfehlen?

Antworten