Base64 selbst machen



  • Jetzt bin ich mit meinem latain am ende ^^

    das hier Funktioniert auch:

    const char* p1 = c;
    		const char* p2 = c++;
    		unsigned int bla = ( ((*p1) & 0x03) << 4 ) + ( (*p2) >> 4) ;
    

    aber ich verstehe den unterschied nicht... geht *c und *(++c) in einer Zeile nicht richtig?



  • leoni_ schrieb:

    Jetzt bin ich mit meinem latain am ende ^^

    das hier Funktioniert auch:

    const char* p1 = c;
    		const char* p2 = c++;
    		unsigned int bla = ( ((*p1) & 0x03) << 4 ) + ( (*p2) >> 4) ;
    

    aber ich verstehe den unterschied nicht... geht *c und *(++c) in einer Zeile nicht richtig?

    ** *c gibt Dir den Wert an der Speicher-Adresse zurück, auf die der Zeiger c **gerade zeigt.

    ** *(++c) macht im Prinzip das selbe, schiebt den Zeiger c **aber gleichzeitig (und zwar bevor der Wert gelesen wird!) um eine Position weiter, d.h. Du bekommst schon den Wert an der "neuen" Adresse.

    Analog würde** *(c++) ebenfalls c **um eine Position weiter schieben, aber noch den Wert der "alten" Adresse zurück liefern.

    Achtung: Von der Verwendung von** *c und *(++c) bzw. *(c++) **innerhalb einer Anweisung ist abzuraten, da die Auswertungsreihenfolge der Argumente nicht unbedingt definiert ist!

    http://stackoverflow.com/questions/24326572/pre-increment-operators-when-using-the-variable-on-the-same-line



  • Danke für deine Antwort,

    hmm das ist schon richtig. ich will ja da an den nächsten character. Und ich erhöhe mit absicht vorher, damit ich dann das B bekomme.

    Warum das nicht in einer Zeile geht, verstehe ich trotzdem nicht.



  • Hast Du meinen Edit bemerkt? 😕

    DeathCubeK schrieb:

    Achtung: Von der Verwendung von** *c und *(++c) bzw. *(c++) **innerhalb einer Anweisung ist abzuraten, da die Auswertungsreihenfolge der Argumente nicht unbedingt definiert ist!

    http://stackoverflow.com/questions/24326572/pre-increment-operators-when-using-the-variable-on-the-same-line

    Folgender Testcode:

    int _tmain(int argc, _TCHAR* argv[])
    {
    	const char *c = &test[0];
    	printf("%c %c\n", *c, *(++c));
    	return 0;
    }
    

    ...erzeugt bei mir folgende Ausgabe:

    b b
    

    😮

    (BTW: "Innerhalb einer Zeile" spielt für C/C++ keine Rolle, da Zeilenumbrüche für den Compiler keine Bedeutung haben und daher völlig optional sind. Es geht um Anweisungen, welche mit Semikolon abgeschlossen/getrennt werden)



  • Vielen Dank für deine Ausführliche Antwort.

    Ich bin jetzt scho am decodieren.

    Ich muss ja jetzt zurück rechnen. D.h. ich muss einen Kommenden Buchsten (Jetzt das Q) wissen welche Position es in der Tabelle hat.

    Das könnte ich jetzt mit Suchen machen oder ich nehme mir die Werte und mach Vergleiche. z.B. A = 65 --> 65-65 --> 0, B = 66 --> 66-65 = 1 usw.

    Ich hab schon gegoogelt aber irgenwie find ich nichts. Wie teuer sind den Vergleichsoperationen gegenüber einer Suche. Ich denke das Vergleichsoperationen von zwei int Variablen viel geringer ist als eine Suche. Aber ich würde es echt gern wissen. Ich weiß aber nicht nach welchen Stichwort ich suchen muss.



  • leoni_ schrieb:

    Vielen Dank für deine Ausführliche Antwort.

    Ich bin jetzt scho am decodieren.

    Ich muss ja jetzt zurück rechnen. D.h. ich muss einen Kommenden Buchsten (Jetzt das Q) wissen welche Position es in der Tabelle hat.

    Das könnte ich jetzt mit Suchen machen oder ich nehme mir die Werte und mach Vergleiche. z.B. A = 65 --> 65-65 --> 0, B = 66 --> 66-65 = 1 usw.

    Ich hab schon gegoogelt aber irgenwie find ich nichts. Wie teuer sind den Vergleichsoperationen gegenüber einer Suche. Ich denke das Vergleichsoperationen von zwei int Variablen viel geringer ist als eine Suche. Aber ich würde es echt gern wissen. Ich weiß aber nicht nach welchen Stichwort ich suchen muss.

    Mach Dir eine Lookup-Tabelle (Array) und verwende das Zeichen, also z.B. 'Q' (was nichts anderes als der Wert 0x51 ist, siehe ASCII-Tabelle), direkt als Index.

    Beispiel:

    int LUT[256];
    
    //Initialisierung der LUT - einmalig am Programmstart auszuführen!
    void init(void)
    {
       LUT['Q'] = 666; //Hier welchen Wert auch immer Du 'Q' zuweisen möchtest
    
       //Und so weiter für alle (relevanten) Zeichen...
    }
    
    //Funktion um für ein Eingabe-Zeichen den zugehörigen Wert abzufragen
    int getValue(const char c)
    {
       return LUT[c];
    }
    


  • das verstehe ich jetzt nicht...

    Ich hab doch 64 Werte und dann muss ich jedesmal nach dem jeweiligen Char suchen?

    Ich könnte das aber auch easy umrechnen.



  • ich hab nochmal drüber nachgedacht habs kapiert... aber dann muss ich alle werte initalisieren... hmm.



  • leoni_ schrieb:

    ... aber dann muss ich alle werte initalisieren... hmm.

    Einmalig, ja! Und man kann das natürlich mit einer Schleife elegant lösen 😉

    void init(void)
    {
       char c = 'A';
       for(int i = 0; i < 64; i++)
       {
          LUT[c] = i;
          c++;
       }
    }
    

    Danach steht in der Deiner LUT:

    LUT['A'] == 0 , LUT['B'] == 1 , LUT['C'] == 2 , und so weiter...



  • DeathCubeK schrieb:

    leoni_ schrieb:

    ... aber dann muss ich alle werte initalisieren... hmm.

    Einmalig, ja! Und man kann das natürlich mit einer Schleife elegant lösen 😉

    void init(void)
    {
       char c = 'A';
       for(int i = 0; i < 64; i++)
       {
          LUT[c] = i;
          c++;
       }
    }
    

    Nach den `Z` geht es dann aber leider falsch weiter.

    DeathCubeK schrieb:

    Danach steht in der Deiner LUT:

    LUT['A'] == 0 , LUT['B'] == 1 , LUT['C'] == 2 , und so weiter...

    sollte wohl eher heissen:

    LUT[0] == 'A' , LUT[1] == 'B' , LUT[2] == 'C'



  • 1. jup nach dem Z muss man aufhören und für klein a mit dem richtigen i weitermachen.

    2. Nein das ist richtig LUT['A'] = 0; Damit ich zurück rechnen kann, will ich ja nicht die Bits von A sondern von der Position der Tabelle...



  • leoni_ schrieb:

    1. jup nach dem Z muss man aufhören und für klein a mit dem richtigen i weitermachen.

    Der Beispielcode erhebt keinen Anspruch auf Vollständigkeit, sondern dient lediglich dazu, das Prinzip zu verdeutlichen.

    Ich werde hier nicht den fertigen Code für leoni_'s Hausarbeit schreiben :p

    2. Nein das ist richtig LUT['A'] = 0; Damit ich zurück rechnen kann, will ich ja nicht die Bits von A sondern von der Position der Tabelle...[/quote]

    Du wirst wohl zwei verschiedene Tabellen benötigen. Je eine zum Base64 kodieren und dekodieren 😉


Anmelden zum Antworten