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;
}








VB: Option _Explicit

Dim As String udata, decoded
udata = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLVBhdWwgUi5FaHJsaWNo"

decoded = decode(udata)

Print udata
Print decoded

Function findIndex& (value As _Unsigned _Byte)
    If Asc("A") <= value And value <= Asc("Z") Then
        findIndex = value - Asc("A")
        Exit Function
    End If
    If Asc("a") <= value And value <= Asc("z") Then
        findIndex = value - Asc("a") + 26
        Exit Function
    End If
    If Asc("0") <= value And value <= Asc("9") Then
        findIndex = value - Asc("0") + 52
        Exit Function
    End If
    If value = Asc("+") Then
        findIndex = 62
        Exit Function
    End If
    If value = Asc("/") Then
        findIndex = 63
        Exit Function
    End If
    findIndex = -1
End Function

Function encode$ (source As String)
    Dim As String Base64: Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    Dim As _Unsigned _Integer64 length: length = Len(source)
    Dim As _Unsigned _Integer64 it, strend
    Dim As Long acc
    Dim As String sink
    strend = length
    While it <> strend
        Dim As _Unsigned _Byte b1, b2, b3, b4
        it = it + 1
        b1 = Asc(Mid$(source, it, 1))
        sink = sink + Mid$(Base64, _SHR(b1, 2), 1)
        acc = _SHL(b1 And &H3, 4)
        If it <> strend Then
            it = it + 1
            b2 = Asc(Mid$(source, it, 1))
            acc = acc Or _SHR(b2, 4)
            sink = sink + Mid$(Base64, acc, 1)
            acc = _SHL(b2 And &HF, 2)
            If it <> strend Then
                it = it + 1
                b3 = Asc(Mid$(source, it, 1))
                acc = acc Or _SHR(b3, 6)
                sink = sink + Mid$(Base64, acc, 1)
                sink = sink + Mid$(Base64, b3 And &H3F, 1)
            Else
                sink = sink + Mid$(Base64, acc, 1)
                sink = sink + "="
            End If
        Else
            sink = sink + Mid$(Base64, acc, 1)
            sink = sink + "="
            sink = sink + "="
        End If
    Wend
    encode = sink
End Function

Function decode$ (source As String)
    Dim As _Unsigned _Integer64 length: length = Len(source)
    Dim As _Unsigned _Integer64 it, strend
    Dim As Long acc
    Dim As String sink
    strend = length
    While it <> strend
        Dim As _Unsigned _Byte b1, b2, b3, b4
        it = it + 1
        b1 = Asc(Mid$(source, it, 1))
        it = it + 1
        b2 = Asc(Mid$(source, it, 1))
        it = it + 1
        b3 = Asc(Mid$(source, it, 1))
        it = it + 1
        b4 = Asc(Mid$(source, it, 1))
        Dim As Long i1, i2
        i1 = findIndex(b1)
        i2 = findIndex(b2)
        acc = _SHL(i1, 2)
        acc = acc Or _SHR(i2, 4)
        sink = sink + Chr$(acc)
        If b3 <> Asc("=") Then
            Dim As Long i3
            i3 = findIndex(b3)
            acc = _SHL(i2 And &HF, 4)
            acc = acc Or _SHR(i3, 2)
            sink = sink + Chr$(acc)
            If b4 <> Asc("=") Then
                Dim As Long i4
                i4 = findIndex(b4)
                acc = _SHL(i3 And &H3, 6)
                acc = acc Or i4
                sink = sink + Chr$(acc)
            End If
        End If
    Wend
    decode = sink
End Function