Oleg Sydorov
Oleg Sydorov

Reputation: 709

How to decode base64 using C?

I am trying to create a C web client for a web API. The API sends a file divided by chunks, base64 encoded, as a JSON string. I was able to receive data and extract the payload from JSON, but I cannot decode base64 encoded chunk using C. For this purpose I use such library: https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c If I try to work with test strings it works fine:

size_t out_len = 0;
unsigned char *test = "U29tZVRlc3RUZXh0";
unsigned char *res = base64_decode(test, strlen(test), &out_len);
printf("%s", res); //prints "SomeTestText"

But when decoding a chunk, for example, one of them you can see here: https://mega.nz/file/K8gDWJiI#oZagaBN2hWFdpUKOv-glE-ySh4JVvnTdRNfgOGY9jzM It returns NULL or only several first symbols. What am I doing wrong? The chunks are fragments of a ZIP archive binary. If I use, for example, Golang for the same purpose, it works as expected... How can I decode my chunks?

Upvotes: 1

Views: 674

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117822

The first bytes in the base64 encoded PK Zip archive (named after its author Phil Katz) you linked to are:

0 0x50 P
1 0x4b K
2 0x03
3 0x04
4 0x14
5 0x00

The four first are \x50\x4b\x03\x04 which is PK Zips "magic" number.

The next two contains the version number. Notice how the sixth byte is 0x00? This is where printf will stop printing since it will interpret that as a string terminator, which is why you will only see PK written to the console. The other three characters are most likely invisible.

Also note that the archive is not complete, so not even if you write it to a file ...

int main(void) {
    size_t out_len = 0;
    unsigned char *res = base64_decode(test, strlen(test), &out_len);
    FILE* fp = fopen("out.zip", "wb");
    if(fp) {
        fwrite(res, out_len, 1, fp);
        fclose(fp);
    }
}

... will you be able to unzip it afterwards. The base64 decoding part does the correct thing though.

Upvotes: 4

chqrlie
chqrlie

Reputation: 145277

A ZIP archive contains binary data. You can decode binary contents with base64_decode(), but you cannot print binary data directly with printf. The decoded chunk is in the array returned by the function and has a length of out_len bytes.

Upvotes: 2

Related Questions