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
    }
    

Anmelden zum Antworten