mir reicht's! Kryptostream muß her!



  • @volkard
    Sollen die Daten denn bereits verschlüsselt im Puffer liegen, oder reicht es, wenn dies erst passiert, wenn der Puffer voll ist und dieser in die Datei geschrieben wird?

    Letzteres wäre natürlich leichter zu implementieren.
    Man könnte dann nämlich leicht den ganzen Puffer an den Verschlüsslungsteil übergeben, dieser verschlüsselt, liefert das Ergebnis zurück und die von streambuf abgeleitete Klasse schreibt das ganze dann in die Datei. Danach kann der Puffer geleert werden und das Spiel beginnt von vorn.

    Die erste Variante sollte allerdings auch nicht viel komplizierter sein.

    Man müßte sich aber auf jeden Fall auf eine Verschlüsselschnittstelle einigen. Es wäre ja schließlich quatsch, wenn der Stream Kentniss über den Algo besitzen müsste.



  • Einfach, möglichst einfach.



  • Hume: Wäre es einfacher für dich, wenn decipher() und encipher() nur noch 2 Parameter hätten und das Resultat in der Form char* zurückgäben?



  • Original erstellt von Doktor Prokt:
    Hume: Wäre es einfacher für dich, wenn decipher() und encipher() nur noch 2 Parameter hätten und das Resultat in der Form char zurückgäben?*

    Ich vermute, am einfachsten ist ein Objekt, das alle Statusinformationen wie Schlüssel als Attribute hat und decipher() und encipher() je nur zwei Parameter, char*buf und size_t len. und daß decipher und encipher ihre Arbeit inplace zu machen haben. Für die selten Fälle, wo inplace nicht geht, kann man sie immer noch so machen, daß sie in ne lokale kopie verschlüsseln und zurückkopieren. Kopierkosten sind eh vernachlässigbar gering.



  • Hm, ich bin mit den Fachausdrücken nicht so vertraut: Was bedeutet inplace und die beiden Parameter buf und len? Wo bleibt der Schlüssel?



  • Original erstellt von Doktor Prokt:
    Hm, ich bin mit den Fachausdrücken nicht so vertraut: Was bedeutet inplace und die beiden Parameter buf und len? Wo bleibt der Schlüssel?

    Inplace heißt, dam man's in dem Puffer tut. Nix rauskopiert. Ist oft effizienter. Und ganz oft einfacher.

    class Caeser
    {
      private:
        char _key;
      public:
        Caesar(char* key)
          _key(key)
        {
        }
        void crypt(char* buf,size_t len)
        {
          for(size_t i=0;i!=len;++i)
            buf[i]+=_key;
        }
        void decrypt(char* buf,size_t len)
        {
          for(size_t i=0;i!=len;++i)
            buf[i]-=_key;
        }
    }
    


  • Ok, mach ich.



  • Hallo,
    also ich stelle mir das so vor, dass der Stream mit einem Verschlüsslungstyp parametrisiert wird.

    Jede Verschlüssungsklasse sammelt alle für die Verschlüsselung benötigten externen Informationen über einen Ctor und speichert diese in Instanzvariablen.

    Außerdem bieten sie Methoden zum Ver- und Entschlüsseln an. Als Parameter würde ich statt Zeiger + Länge zwei Iteratoren vorschlagen (begin, end). Letztlich können das natürlich zwei char-Zeiger sein.
    Zeiger + Länge geht aber natürlich auch.

    Der Cryptostream speichert ein Verschlüsselungsobjekt. Wann immer Daten ver-/entschlüsselt werden müssen, werden die entsprechenden Methoden des Verschlüsselungsobjekts aufgerufen.



  • Toll. Da braucht man einmal > 6 Minuten für einen Beitrag und schon ist er überflüssig images/smiles/icon_smile.gif



  • Original erstellt von HumeSikkins:
    ja, ja, ja!

    Klar, zwei Iteratoren, gerne.
    Ähm, nochwas ziemlich wichtiges. Einige Verschlüsseler wünchen bestimmte Blocklängen um so richtig geil abzugehen.
    Kann der Verschlüsseler die bestimmen und der Stream die nehmen?

    Oder würde das die Funktion von flush einfach kaputthauen? Na, und wenn schon, Cryptstreams können genausogut ohne flush leben, ist vielleicht besser so.



  • @volkard

    da gibt es ein Problem:
    ich war gerade am Verzweifeln, warum folgender Code einen Speicherzugriffsfehler liefert:

    int main ()
    {
        char* x = "Hallo, Welt!";
        x[0] = 2;
    }
    

    Habe dann im Stroustrup gelesen, daß ein über ein Zeichenkettenliteral initialisiertes char* immer als const interpretiert wird und das Resultat einer Zuweisung also undefiniert ist. obj.encipher(str,strlen(str); funktioniert also nicht, wenn str über ein Literal initialisiert wurde. Ärgerlich.



  • char* x = "Hallo, Welt!";
    zeigt auf Speicher innerhalb der exe und der shared, discardable und readonly. Also er gehört Dir net.
    char x[] = "Hallo, Welt!";
    ist korrekt.
    Hier wird ein char x[] auf dem Stack angelegt, der Dir gehört und "Hallo, Welt!" gleich reinkopiert. Damit kannste dann machen, was Du magst.



  • Naja, man muss dann eben Arrays aus char nehmen.

    Der gute Mann hieß Vigenere, habe mich vertan.

    // vigenere.h
    #ifndef _VIGENERE_
    #define _VIGENERE_
    
    #include <cstddef>
    
    typedef unsigned char byte;
    
    class Vigenere
    {
     private:
        byte* key;
        void getBytes (byte* b, unsigned int k, size_t size);
     public:
        static const unsigned long int keySize = 4;
        Vigenere(unsigned int k);
        void encipher (char* data, size_t size);
        void decipher (char* data, size_t size);
    };
    
    #endif // _VIGENERE
    
    // vigenere.cpp
    #include "vigenere.h"
    
    Vigenere::Vigenere (unsigned int k)
    {
        key = new byte[4];
        getBytes(key, k, keySize);
    }
    
    void Vigenere::getBytes (byte* b, unsigned int n, size_t s)
    {
        unsigned int mask = 0;
        for (unsigned i = 0; i < s; i++)
        {
        mask = (mask + 1) * 0x100 - 1;
        b[i] = (n & mask) >> (8 * i);
        }
    }
    
    void Vigenere::encipher (char* data, size_t size)
    {
        for (unsigned i = 0, j = 0 ; i < size; i++, (!(i % keySize) ? j = 0 : j++))
        data[i] += key[j];
    }
    
    void Vigenere::decipher (char* data, size_t size)
    {
        for (unsigned i = 0, j = 0; i < size; i++, (!(i % keySize) ? j = 0 : j++))
        data[i] -= key[j];
    }
    
    // main.cpp
    #include <iostream>
    #include "vigenere.h"
    using namespace std;
    
    int main ()
    {
        char x[] = "Hallo, Welt!";
        Vigenere a(1230152);
        a.encipher(x,strlen(x));
        cout << x << endl;
        a.decipher(x,strlen(x));
        cout << x << endl;
    }
    

    [ Dieser Beitrag wurde am 17.04.2002 um 21:20 Uhr von Doktor Prokt editiert. ]



  • soll ich nach Doktor Prokt vorlage den crc32 algo schreiben? wolltet ihr nicht iteratoren?
    MD5 algo habe ich schon gefunden, (habe es aber noch nicht versucht zu verstehen) aber umschreiben könnte ich ihn bestimt



  • Original erstellt von Dimah:
    soll ich nach Doktor Prokt vorlage den crc32 algo schreiben? wolltet ihr nicht iteratoren?

    void Vigenere::encipher(char* start,char* end)
    {
       encipher(start,end-start);
    }
    

    [ Dieser Beitrag wurde am 17.04.2002 um 23:14 Uhr von volkard editiert. ]



  • Original erstellt von Dimah:
    soll ich nach Doktor Prokt vorlage den crc32 algo schreiben?

    Jetzt wären erstmal die Stream-Sachen dran. Denn klappen die nicht, können wir das Projekt erstmal wegschmeißen.



  • Original erstellt von volkard:
    void Vigenere::encipher(char* start,char* end)
    {
       encipher(start,end-start);
    }
    

    hä? rekrisiv und dan noch pointer mit einander verrächnen (undefieniertes verhalten)
    was soll das bringen?

    e: kein beitrag ohne edit images/smiles/icon_smile.gif

    [ Dieser Beitrag wurde am 17.04.2002 um 23:28 Uhr von Dimah editiert. ]



  • die
    void Vigenere::encipher(char*,char*)
    ruft die
    void Vigenere::encipher(char*,size_t)
    auf.

    end-start==len, wenn start+len==end



  • ok wieder was zu gelernt
    aber wie ich es in erinerung habe ist pointer mit pointer nicht erlaubt
    wenn schon dan reinterpret_cast in ints,

    [ Dieser Beitrag wurde am 17.04.2002 um 23:43 Uhr von Dimah editiert. ]



  • Mit strlen geht das IMHO nicht, da diese Funktion bei einer \0 aufhört zu zählen. Wenn du jetzt binäre Daten hast wo eine \0 vorkommt, wird nicht alles verschlüsselt. Ich glaube die Länge muss auf jeden Fall übergeben werden!


Anmelden zum Antworten