B64 String decodieren
-
Hallo,
ich habe folgenden Code versucht zu schreiben..
Aber leider ist die Ausgabe nicht immer korrekt wegen der Terminierung wenn Beispielsweise ein == oder nur ein = im String ist ändert sich da irgendwie die Terminierung und im Decodierten String befinden sich irgendein wirres Zeichen.
Hier mal der Code:void base64_out (char *buf, unsigned char *obuf, int len) { int nprbytes; char *p = buf; while (ascii[(int) *(p++)] <= 63); if( (buf[len] == '=') && (buf[len-1] == '=') ) nprbytes = len - 1 - 1; else if(buf[len-1] == '=') nprbytes = len -1; else nprbytes = len; // und nochmal -1 ...sonst bearbeitet es ein byte zu viel // nprbytes = len - 1; while (nprbytes > 4 && *buf != '\0') { *(obuf++) = (ascii[(int) *buf] << 2 | ascii[(int) buf[1]] >> 4); *(obuf++) = (ascii[(int) buf[1]] << 4 | ascii[(int) buf[2]] >> 2); *(obuf++) = (ascii[(int) buf[2]] << 6 | ascii[(int) buf[3]]); buf += 4; nprbytes -= 4; } if (nprbytes > 1) *(obuf++) = (ascii[(int) *buf] << 2 | ascii[(int) buf[1]] >> 4); if (nprbytes > 2) *(obuf++) = (ascii[(int) buf[1]] << 4 | ascii[(int) buf[2]] >> 2); if (nprbytes > 3) *(obuf++) = (ascii[(int) buf[2]] << 6 | ascii[(int) buf[3]]); *(obuf)++ = '\0'; }
Kann mir jemand sagen wo dort der Fehler ist ?
-
Sorry, mit sowas hab ich mich noch nicht auseinandergesetzt, aber passen deine Bedingungen hier?
if( (buf[len] == '=') && (buf[len-1] == '=') ) nprbytes = len - 1 - 1; else if(buf[len-1] == '=') // wenn das vorletzte Zeichen ein =, dann wirklich nur -1? nprbytes = len -1;
-
Ich habe mal vor sehr sehr langer Zeit Base64 implementiert, aber soweit ich mich erinnern kann, hat es funktioniert. Vielleicht hilft es dir:
static const char gB64Base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* ---------------------------------------------------------------- Base64 encoding // Encodes a ASCII string into a Base64 string. Parameter: Destination for the encoded Base64 string. Source of the unencoded ASCII string. MaxLen of the source string. The destination string should be 1/3 larger than the source. ---------------------------------------------------------------- */ int B64Encode(char * pEncodedDestination, const char * pUnencodedSource, int pUnencodedSourceLength, bool pString) { int lCounter; unsigned char *lTempPointer = (unsigned char *)pEncodedDestination; unsigned char *lUnencodedSource = (unsigned char *)pUnencodedSource; // Encode the ASCII string for( lCounter = 0; lCounter < pUnencodedSourceLength - 2; lCounter += 3 ) { *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter + 0] & 0xFC) >> 2) | 0x00]; *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter + 0] & 0x03) << 4) | (lUnencodedSource[lCounter + 1] >> 4)]; *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter + 1] & 0x0F) << 2) | (lUnencodedSource[lCounter + 2] >> 6)]; *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter + 2] & 0x3F) << 0) | 0x00]; } // Processes the last two bytes if the source was not divisible by 3. if( lCounter < pUnencodedSourceLength ) { *lTempPointer++ = gB64Base[(lUnencodedSource[lCounter] >> 2) & 0x3F]; if( lCounter == (pUnencodedSourceLength - 1) ) { *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter] & 0x3) << 4)]; *lTempPointer++ = '='; } else { *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter] & 0x3) << 4) | ((int) (lUnencodedSource[lCounter + 1] & 0xF0) >> 4)]; *lTempPointer++ = gB64Base[((lUnencodedSource[lCounter + 1] & 0xF) << 2)]; } *lTempPointer++ = '='; } // End if( pString ) { *lTempPointer++ = '\0'; } return( (int) ((lTempPointer - (unsigned char *)pEncodedDestination) - 1) ); // Size of the encoded destination } /* ---------------------------------------------------------------- Base64 decoding // Decodes a Base64 string into a ASCII string. Parameter: Destination for the decoded ASCII string. Source of the undecoded Base64 string. MaxLen of the source string. The destination string can be 1/3 smaller than the source. ---------------------------------------------------------------- */ int B64Decode(char * pDecodedDestination, const char * pEncodedSource, int pEncodedSourceLength, bool pString) { int lBase64Counter; unsigned char * lBase64Buffer = (unsigned char*) malloc(pEncodedSourceLength); unsigned char * lTempPointer = (unsigned char*) pDecodedDestination; // Get the Base64 values for( int i = 0; i < pEncodedSourceLength; i++ ) { for( lBase64Counter = 0; lBase64Counter < sizeof(gB64Base); lBase64Counter++ ) { if( pEncodedSource[i] == gB64Base[lBase64Counter] ) { lBase64Buffer[i] = lBase64Counter; break; } } if( lBase64Counter == sizeof(gB64Base) ) { lBase64Buffer[i] = 0x00; } } // Decode the Base64 values into a ASCII string for( int i = 0; i < pEncodedSourceLength; i += 4 ) { *lTempPointer++ = (lBase64Buffer[i + 0] << 2) | (lBase64Buffer[i + 1] >> 4); *lTempPointer++ = (lBase64Buffer[i + 1] << 4) | (lBase64Buffer[i + 2] >> 2); *lTempPointer++ = (lBase64Buffer[i + 2] << 6) | (lBase64Buffer[i + 3] >> 0); } // End if( pString ) { *lTempPointer++ = '\0'; } free(lBase64Buffer); return( (int) ((lTempPointer - (unsigned char *)pDecodedDestination) - 1) ); // Size of the decoded destination }