Announcement

Collapse
No announcement yet.

Base64-Algo falsches Byte !?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Base64-Algo falsches Byte !?

    Hallo,

    Ich habe folgendes Problem, ich versuche den Base64-Algo von der http://base64.sourceforge.net/ in eine klasse zu packen das hat auch erstmal wunderbar geklappt.
    Intern Kodiert die Klasse bzw Dekodiert die Klasse auf den ersten Blick vollkommen korrekt. Dann habe ich testweise versucht den kodierten text per fremdsoftware zu
    dekodieren. Dabei ist mir aufgefallen meine Klasse packt am Ende des Strings immer noch ein zusätzliches Byte dran. Nur leider kann ich mir nicht erklären wo her dieses
    kommt. Und den Fehler Code kann ich selber nicht finden. Ich bräuchte da ein zweites fremdes paar Augen.

    Mehr kann ich eigentlich nicht zu sagen, da ich echt grad vollkommen ahnungslos bin. Ich hoffe jemand mag sich erbarmen und sich den Code durchschauen und mich auf meinen
    Fehler den ich irgendwo gemacht habe muss aufmerksam machen.

    Hier mal der Code:

    Der Header


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    /*
    ** Translation Table as described in RFC1113
    */
    static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    
    /*
    ** Translation Table to decode (created by author)
    */
    static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
    
    
    
    
    /*
    ** encodeblock
    **
    ** encode 3 8-bit binary bytes as 4 '6-bit' characters
    */
    static void encodeblock( unsigned char *in, unsigned char *out, int len )
    {
        out[0] = (unsigned char) cb64[ (int)(in[0] >> 2) ];
        out[1] = (unsigned char) cb64[ (int)(((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)) ];
        out[2] = (unsigned char) (len > 1 ? cb64[ (int)(((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)) ] : '=');
        out[3] = (unsigned char) (len > 2 ? cb64[ (int)(in[2] & 0x3f) ] : '=');
    }
    
    
    /*
    ** decodeblock
    **
    ** decode 4 '6-bit' characters into 3 8-bit binary bytes
    */
    static void decodeblock( unsigned char *in, unsigned char *out )
    {   
        out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4);
        out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2);
        out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]);
    }
    
    
    #define B64_DEF_LINE_SIZE   72
    #define B64_MIN_LINE_SIZE    4
    
    
    #define THIS_OPT(ac, av) ((char)(ac > 1 ? av[1][0] == '-' ? av[1][1] : 0 : 0))
    
    
    namespace gf
    {
        namespace Engine
        {
            namespace Base64
            {
                class Base64
                {
                private:
                    
                    std::string                     m_EncodeText;
                    std::string                     m_DecodeText;
                    
                    unsigned char*                  m_in;
                    unsigned char*                  m_out;
                    int                             m_len;
                    
                protected:
                    
                    void            decodeblock();
                    void            encodeblock();
                    
                    
                public:
                    Base64(std::string text, bool flag);
                    ~Base64();
                    
                    std::string Decode();
                    std::string Encode();
                    
                    std::string getDecode();
                    std::string getEncode();
    //                
    //                void        setDecode(std::string);
    ////                void        setEncode(std::string);
                    
                    
                };
            }
        }
    }


    Die Quellcode
    Code:
    #include <string>
    
    
    #include "../../include/Engine/Base64.h"
    
    
    namespace gf
    {
        namespace Engine
        {
            namespace Base64
            {
                Base64::Base64(std::string text, bool flag)
                {
                    if(flag==true)
                        this->m_DecodeText = text;
                    if(flag!=true)
                        this->m_EncodeText = text;
                }
                
                Base64::~Base64()
                {
                    
                }
                
                void Base64::decodeblock()
                {
                    ::decodeblock(m_in,m_out);
                }
                
                void Base64::encodeblock()
                {
                    ::encodeblock(m_in,m_out,m_len);
                }
                
                std::string Base64::Decode()
                {
                    int v;
                    int len,j;
                    std::string::iterator iter;
                    std::string::iterator iter2;
                    this->m_in = NULL;
                    this->m_out= NULL;
                    
                    this->m_in = new unsigned char[4];
                    this->m_out = new unsigned char[3];
                    iter       = this->m_EncodeText.begin();
                    
                    *this->m_in  = static_cast<unsigned char>(0);
                    *this->m_out = static_cast<unsigned char>(0);
                    
                    for(int i=0; i < this->m_EncodeText.size();i++)
                    {
                        for(len = 0, j=0; ((j<4) && (i < this->m_EncodeText.size()-1) == 0);j++)
                        {
                            v = (*iter++);
                            for(;i < this->m_EncodeText.size() && v == 0;)
                            {
                                v = ((v < 43 || v > 122) ? 0 : (int) cd64[ v - 43 ]);
                                if(v != 0)
                                {
                                    v = ((v == (int)'$') ? 0 : v - 61);
                                }
                            }
                            
                            if(i<this->m_EncodeText.size()-1)//Optional, only used because of equality of the original code
                            {
                                this->m_len++;
                                if( v != 0 )
                                {
                                    this->m_in[ j ] = (unsigned char) (v - 1);
                                }
                            }
                            else
                            {
                                this->m_in[ j ] = static_cast<unsigned char>(0);
                            }
                        }
                        
                        if(len > 0)
                        {
                            this->decodeblock();
                            for(int i = 0; i< len-1;++i)
                            {
                                this->m_DecodeText.push_back(this->m_out[i]);
                            }
                        }
                    }
                    
                    return this->m_DecodeText;
                }
                
                std::string Base64::Encode()
                {
                    int v;
                    int len,j,blocksout=0;
                    std::string::iterator iter;
                    std::string::iterator iter2;
                    this->m_in = NULL;
                    this->m_out= NULL;
                    
                    this->m_in = new unsigned char[3];
                    this->m_out = new unsigned char[4];
                    iter       = this->m_DecodeText.begin();
                    
                    
                    for(int i = 0; i<this->m_DecodeText.size();i++)
                    {
                        len = 0;
                        for(j=0;j < 3; j++)
                        {
                            //Get character of the Decodetext
                            this->m_in[j] = (*iter++);
                            
                            if(i<this->m_DecodeText.size())
                            {
                                len++;
                            }
                            else
                            {
                                this->m_in[ j ] = static_cast<unsigned char>(0);
                            }
                        }
                        
                        if( len > 0)
                        {
                            ::encodeblock(this->m_in,this->m_out,len);
                            for( j = 0; j < 4; j++)
                            {
                                this->m_EncodeText.push_back(this->m_out[j]);
                            }
                            blocksout++;
                        }
                        
                      
                    }
                    
                    return this->m_EncodeText;
                }
                
                std::string Base64::getDecode()
                {
                    return this->m_DecodeText;
                }
                
                std::string Base64::getEncode()
                {
                    return this->m_EncodeText;
                }
                
                
    
    
            }
        }
    }
    Zuletzt editiert von ExOfDe; 11.07.2013, 20:14.

  • #2
    Dabei ist mir aufgefallen meine Klasse packt am Ende des Strings immer noch ein zusätzliches Byte dran.
    Wie hast du das festgestellt. Was für ein Byte? Mittels eines Debuggers sollte das doch zu finden sein...
    Christian

    Comment


    • #3
      Hier kurz ein Beispiel ich versuche "Hallo Welt" zu codieren und jedes mal bekomme ich ein anderes Ergebnis:

      1. SGFsbG8gV2VsdAAAAAAAACEAAAAAAAAAAAAA4MV/
      2. SGFsbG8gV2VsdAAAAAAAACEAAAAAAAAAAAAAyiZ/
      3. SGFsbG8gV2VsdAAAAAAAACEAAAAAAAAAAAAAWMt/
      4. SGFsbG8gV2VsdAAAAAAAACEAAAAAAAAAAAAA2OB/
      5. SGFsbG8gV2VsdAAAAAAAACEAAAAAAAAAAAAAK9x/

      Man muss auf das Ende Achten

      Comment


      • #4
        Das teste das mal mit den Originalcode von Sourceforge. Des Weiteren sehe ich da 3 andere Bytes und nicht eins
        Christian

        Comment


        • #5
          Stimmt da hast du recht sind drei bytes bzw scheinbar noch mehr und nicht eins, vor verzweifelung schon verzählt peinlich peinlich. Mit dem Debugger bin ich auch schon durch gegangen.
          Das Ergebnis war das ich scheinbar ausserhalb des strings arbeite. Nur mein Problem ich arbeite ja mit nem Iterator,nicht durchgehend aber halt um auf die einzelnen
          Elemente zuzugreifen, und die greifen ja nur auf den Bereich zu denen sie ja auch Zugriff haben und nicht mehr. Oder unterliege da einem Irrtum?

          Nun habe es jetzt mit dem Orginalcode getest raus bekam ich dabei dies:
          SGFsbG8gV2VsdA0K

          Immer. beim anpassen habe ich irgendwo nen denkfehler begangen...
          Zuletzt editiert von ExOfDe; 11.07.2013, 20:18.

          Comment


          • #6
            Hab die Lösung ... manomann meine annahme mit den iteratoren ist falsch gewesen. habe da jetzt eine überprüfung eingefügt
            und tada man bekommt jetzt immer das gleiche ergebnis raus. Ist zwar immer noch nicht ganz das selbe wie beim orginal code
            aber dekodierbar: "SGFsbG8gV2VsdG==" := "Hallo Welt" auch mit fremdsoftware^^

            hier die beiden entsprechenden Codestellen:
            Decode
            Code:
            ...
            
                                for(len = 0, j=0; ((j<4) && (i < this->m_EncodeText.size()-1) == 0 );j++)
                                {
                                    if(iter == this->m_EncodeText.end())
                                        break;
                                    v = (*iter++);
                                    for(;i < this->m_EncodeText.size() && v == 0;)
                                    {
                                        v = ((v < 43 || v > 122) ? 0 : (int) cd64[ v - 43 ]);
                                        if(v != 0)
                                        {
                                            v = ((v == (int)'$') ? 0 : v - 61);
                                        }
                                    }
            
            ...
            Encode
            Code:
            ...
            
                            for(int i = 0; i<this->m_DecodeText.size();i++)
                            {
                                len = 0;
                                for(j=0;j < 3 ; j++)
                                {
                                    //Get character of the Decodetext
                                    if(iter == this->m_DecodeText.end())
                                        break;
                                    this->m_in[j] = (*iter++);
                                    
                                    if(i<this->m_DecodeText.size())
                                    {
                                        len++;
                                    }
                                    else
                                    {
                                        this->m_in[ j ] = static_cast<unsigned char>(0);
                                    }
                                }
            
            ...

            Comment


            • #7
              Jetzt tut sich ein weiteres Problem meiner Klasse auf. Wenn ich einen klartext habe kann ich diesen ohne probleme verschlüsseln.
              Wenn ich die gleiche Klasseninstanz zum entschlüsseln nehme wie zum verschlüsseln, funktioniert dies ohne Probleme.

              Wenn ich aber nun eine neue Klasseninstanz der selben Klasse erzeuge und mit dieser Verschlüsselten Text in Klartext umwandeln
              möchte. bekomme ich nur einen leeren string .... miese sache

              Comment


              • #8
                Kenne jetzt den ursprünglichen Code nciht, aber es scheint deine Klasse ist auch viel zu kompliziert aufgebaut:

                Wozu die 5 Methoden?
                Base64(std::string text, bool flag);
                ~Base64();

                std::string Decode();
                std::string Encode();

                std::string getDecode();
                std::string getEncode();

                Wenn ich etwas encodieren oder decodieren will, habe ich genau 1 Parameter zur Übergabe und 1 Rückgabewert. Wozu der Umweg uüber eine extra Methode die den text setzt und sogar noch angibt was passieren soll?
                stringecode(string text) -> decodiert und gibt den decodierten String zurück
                string:Enccode(string text) -> encodiert und gibt den encodierten String zurück
                Mehr brauchsts nichts
                Christian

                Comment

                Working...
                X