0

I already used a lot of different functions to decode Base64 encoded char array in C. Right now, I am using this function to decode Base64 char array.

    unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned char* out) {

    unsigned int i=0, j=0, k=0, s[4];

    for (i=0;i<in_len;i++) {
        s[j++]=b64_int(*(in+i));
        if (j==4) {
            out[k+0] = ((s[0]&255)<<2)+((s[1]&0x30)>>4);
            if (s[2]!=64) {
                out[k+1] = ((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2);
                if ((s[3]!=64)) {
                    out[k+2] = ((s[2]&0x03)<<6)+(s[3]); k+=3;
                } else {
                    k+=2;
                }
            } else {
                k+=1;
            }
            j=0;
        }
    }

    return k;
}

The problem is, that for a Base64 string like this QKSRjAEAAAAB3bW3rVpoJOA8bsb3eEuEEDiq, I am getting a string with only five characters, even the decoded text should be much longer. I tried to debug the code and it is because the result of the bit shift for the sixth character is 0, which unexpectedly ends the string. Online Base64 decoders decoded the mentioned string without problems.

I then want to convert the decoded string to hex. I am doing that like this:

for (int i = 0, j = 0; i < size; ++i, j += 2) {
                sprintf(data_hex + j, "%02x", decoded_data[i] & 0xff);
            }

Example of expected input: QKSRjAEAAAAB3bW3rVpoJOA8bsb3eEuEEDiq

Example of expected output: 40a4918c0100000001ddb5b7ad5a6824e03c6ec6f7784b841038aa

Thank you for your response.

Jakub J.
  • 11
  • 6

1 Answers1

0

Well, it took awhile to figure out where you got this code from. The key was realizing that b64_int() is not a standard library function.

So for posterity, the original source for your code is here, in files base64.h and base64.cc.

Here is the program that works:

#include <stdio.h>
#include <string.h>
#include "base64.h"

int main(void) {

  unsigned char in[] = "QKSRjAEAAAAB3bW3rVpoJOA8bsb3eEuEEDiq\0";
  int inLength = strlen((char*)in);

  unsigned char out[1000]; 
  unsigned int outLength = b64_decode(in, inLength, out);
  
  // Prints the result in Hexadecimal format.
  for (int i = 0; i < outLength; i++)
    printf("%x", out[i]);

  printf("\n");
  return 0;
}

The key is capturing the return value of the b64_decode(), which tells you how many bytes to expect in the result. It's unclear if you did this or not, since you didn't provide a code example of your program calling the b64_decode() function.

Working online demo

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Thank you for your response. That works fine, just for me the base64 encoded data does not have the '\0' terminator and I need to store the result in hexadecimal format for other purposes, and that is why I use sprintf in my example. – Jakub J. Oct 19 '20 at 09:49