Task: Base64 decode data
C: #include <stdio.h>
#include <stdlib.h>

typedef unsigned char ubyte;
const ubyte BASE64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int findIndex(const ubyte val) {
    if ('A' <= val && val <= 'Z') {
        return val - 'A';
    }
    if ('a' <= val && val <= 'z') {
        return val - 'a' + 26;
    }
    if ('0' <= val && val <= '9') {
        return val - '0' + 52;
    }
    if (val == '+') {
        return 62;
    }
    if (val == '/') {
        return 63;
    }
    return -1;
}

int decode(const ubyte source[], ubyte sink[]) {
    const size_t length = strlen(source);
    const ubyte *it = source;
    const ubyte *end = source + length;
    int acc;

    if (length % 4 != 0) {
        return 1;
    }

    while (it != end) {
        const ubyte b1 = *it++;
        const ubyte b2 = *it++;
        const ubyte b3 = *it++;         
        const ubyte b4 = *it++;         

        const int i1 = findIndex(b1);
        const int i2 = findIndex(b2);

        acc = i1 << 2;                  
        acc |= i2 >> 4;                 
        *sink++ = acc;                  

        if (b3 != '=') {
            const int i3 = findIndex(b3);

            acc = (i2 & 0xF) << 4;      
            acc += i3 >> 2;             
            *sink++ = acc;              

            if (b4 != '=') {
                const int i4 = findIndex(b4);

                acc = (i3 & 0x3) << 6;  
                acc |= i4;              
                *sink++ = acc;          
            }
        }
    }

    *sink = '\0';   
    return 0;
}

int main() {
    ubyte data[] = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLVBhdWwgUi5FaHJsaWNo";
    ubyte decoded[1024];

    printf("%s\n\n", data);
    decode(data, decoded);
    printf("%s\n\n", decoded);

    return 0;
}

C++: #include <algorithm>
#include <iostream>
#include <string>
#include <vector>

typedef unsigned char ubyte;
const auto BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

std::vector<ubyte> encode(const std::vector<ubyte>& source) {
    auto it = source.cbegin();
    auto end = source.cend();

    std::vector<ubyte> sink;
    while (it != end) {
        auto b1 = *it++;
        int acc;

        sink.push_back(BASE64[b1 >> 2]);            

        acc = (b1 & 0x3) << 4;                      
        if (it != end) {
            auto b2 = *it++;
            acc |= (b2 >> 4);                       

            sink.push_back(BASE64[acc]);            

            acc = (b2 & 0xF) << 2;                  
            if (it != end) {
                auto b3 = *it++;
                acc |= (b3 >> 6);                   

                sink.push_back(BASE64[acc]);        
                sink.push_back(BASE64[b3 & 0x3F]);  
            } else {
                sink.push_back(BASE64[acc]);        
                sink.push_back('=');                
            }
        } else {
            sink.push_back(BASE64[acc]);            
            sink.push_back('=');                    
            sink.push_back('=');                    
        }
    }
    return sink;
}

int findIndex(ubyte val) {
    if ('A' <= val && val <= 'Z') {
        return val - 'A';
    }
    if ('a' <= val && val <= 'z') {
        return val - 'a' + 26;
    }
    if ('0' <= val && val <= '9') {
        return val - '0' + 52;
    }
    if ('+' == val) {
        return 62;
    }
    if ('/' == val) {
        return 63;
    }
    return -1;
}

std::vector<ubyte> decode(const std::vector<ubyte>& source) {
    if (source.size() % 4 != 0) {
        throw new std::runtime_error("Error in size to the decode method");
    }

    auto it = source.cbegin();
    auto end = source.cend();

    std::vector<ubyte> sink;
    while (it != end) {
        auto b1 = *it++;
        auto b2 = *it++;
        auto b3 = *it++; 
        auto b4 = *it++; 

        auto i1 = findIndex(b1);
        auto i2 = findIndex(b2);
        auto acc = i1 << 2;     
        acc |= i2 >> 4;         

        sink.push_back(acc);    

        if (b3 != '=') {
            auto i3 = findIndex(b3);

            acc = (i2 & 0xF) << 4;  
            acc |= i3 >> 2;         

            sink.push_back(acc);    

            if (b4 != '=') {
                auto i4 = findIndex(b4);

                acc = (i3 & 0x3) << 6;  
                acc |= i4;              

                sink.push_back(acc);    
            }
        }
    }
    return sink;
}

int main() {
    using namespace std;

    string data = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLVBhdWwgUi5FaHJsaWNo";
    vector<ubyte> datav{ begin(data), end(data) };
    cout << data << "\n\n" << decode(datav).data() << endl;

    return 0;
}