2016-12-03 17 views
-2

ich eine große Datei (500 MB)Windows-API-base64 kodieren/Decod

I this code verwenden, um base64 wollen, aber es funktioniert nicht für eine große Datei

Ich teste CryptStringToBinary aber es funktioniert nicht zu

was soll ich tun ????

+0

Kompilieren Sie Ihre Anwendung als 64-Bit-Anwendung. Sowohl dieser Code als auch CryptStringToBinary benötigen wahrscheinlich 500 MB Speicher, um die letzte Zeichenfolge zu speichern. Das wird mehr als wahrscheinlich nicht mit einer 32-Bit-App passieren. – PaulMcKenzie

+0

@PaulMcKenzie Es funktioniert, aber mein Lehrer lässt uns die Einstellungen nicht ändern, wir sollten dies mit den Standardeinstellungen tun – jaliyevic

+0

Sagen Sie Ihrem Lehrer, dass Sie keine Magie ausführen können. Wenn Sie diese Funktionen verwenden und 500MB + Strings generieren müssen, wird dies mit einer 32-Bit-Anwendung nicht einfach passieren. Selbst wenn du kaum durchkommen würdest, hast du eine Menge Speicher verbraucht, dass deine App aufgrund von Speicherermüdung irgendwo anders abgestürzt ist. Das einzige, was vorgeschlagen wird, ist eine Implementierung zu finden, die die Daten auf die Festplatte schreibt, während die base64-Kodierung/Dekodierung erzeugt wird, und nicht auf einer Zeichenkette basiert. – PaulMcKenzie

Antwort

0

Das Problem ist eindeutig, dass nicht genügend Speicher vorhanden ist, um eine 500 Megabyte-Zeichenfolge in einer 32-Bit-Anwendung zu speichern.

Die eine Lösung wird von der this link angedeutet, die die Daten in eine Zeichenfolge schreibt. Unter der Annahme, dass der Code korrekt funktioniert, ist es nicht schwer, ihn so anzupassen, dass er in einen Dateistream schreibt.

#include <windows.h> 
#include <fstream> 

static const wchar_t *Base64Digits = L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

int Base64Encode(const BYTE* pSrc, int nLenSrc, std::wostream& pDstStrm, int nLenDst) 
{ 
    wchar_t pDst[4]; 
    int nLenOut = 0; 

    while (nLenSrc > 0) { 
     if (nLenDst < 4) return(0); 
     int len = 0; 
     BYTE s1 = pSrc[len++]; 
     BYTE s2 = (nLenSrc > 1) ? pSrc[len++] : 0; 
     BYTE s3 = (nLenSrc > 2) ? pSrc[len++] : 0; 
     pSrc += len; 
     nLenSrc -= len; 

     //------------------ lookup the right digits for output 
     pDst[0] = Base64Digits[(s1 >> 2) & 0x3F]; 
     pDst[1] = Base64Digits[(((s1 & 0x3) << 4) | ((s2 >> 4) & 0xF)) & 0x3F]; 
     pDst[2] = Base64Digits[(((s2 & 0xF) << 2) | ((s3 >> 6) & 0x3)) & 0x3F]; 
     pDst[3] = Base64Digits[s3 & 0x3F]; 

     //--------- end of input handling 
     if (len < 3) { // less than 24 src bits encoded, pad with '=' 
      pDst[3] = L'='; 
      if (len == 1) 
       pDst[2] = L'='; 
     } 

     nLenOut += 4; 

     // write the data to a file 
     pDstStrm.write(pDst,4); 

     nLenDst -= 4; 
    } 

    if (nLenDst > 0) *pDst = 0; 

    return (nLenOut); 
} 

Die einzigen vorgenommenen Änderungen waren die 4 Bytes zu einem breiten Strom zu schreiben, anstatt die Daten in eine Reihe von Anhängen

Hier ist ein Beispiel Aufruf:

int main() 
{ 
    std::wofstream ofs(L"testfile.out"); 
    Base64Encode((BYTE*)"This is a test", strlen("This is a test"), ofs, 1000); 
} 

Die oben ein produziert Datei mit der Base64-Zeichenfolge VGhpcyBpcyBhIHRlc3Q=, die bei der Decodierung This is a test produziert.

Beachten Sie, dass der Parameter std::wostream ist, was bedeutet, dass jede breite Ausgangsstromklasse (wie) ebenfalls funktioniert.

+0

danke, es funktioniert, aber es ist nicht genau das, was ich will. - Ist es möglich, den Zeiger mit 'setfilepointer' zu ändern und die Datei vom zweiten Chunk zu lesen? – jaliyevic