Below is base64 decoding function:
MAP
ezh::FromBase64(STRING input_buf), STRING
END
ezh::FromBase64 PROCEDURE(STRING input_buf)
B64index LONG, DIM(256), STATIC
in_len LONG, AUTO
out_buf STRING((LEN(input_buf) / 4) * 3 + 3)
L LONG, AUTO
out_len LONG, AUTO
pad LONG, AUTO
i LONG, AUTO
j LONG, AUTO
n LONG, AUTO
b1 LONG, AUTO
b2 LONG, AUTO
b3 LONG, AUTO
b4 LONG, AUTO
c1 BYTE, AUTO
c2 BYTE, AUTO
c3 BYTE, AUTO
c4 BYTE, AUTO
CODE
in_len = LEN(input_buf)
IF in_len = 0
RETURN ''
END
IF B64index[44] = 0
DO Build_B64
END
IF (in_len % 4) OR (input_buf[in_len] = '=')
pad = 1
ELSE
pad = 0
END
L = ((INT((in_len + 3) / 4) - pad) * 4)
out_len = INT(L / 4) * 3 + pad
j = 1
LOOP i = 1 TO L BY 4
c1 = VAL(input_buf[i+0])+1
c2 = VAL(input_buf[i+1])+1
c3 = VAL(input_buf[i+2])+1
c4 = VAL(input_buf[i+3])+1
b1 = BSHIFT(B64index[c1], 18)
b2 = BSHIFT(B64index[c2], 12)
b3 = BSHIFT(B64index[c3], 6)
b4 = B64index[c4]
n = BOR(b1, BOR(b2, BOR(b3, b4)))
b1 = BSHIFT(n, -16)
b2 = BAND(BSHIFT(n, -8), 0FFh)
b3 = BAND(n, 0FFh)
out_buf[j] = CHR(b1); j += 1
out_buf[j] = CHR(b2); j += 1
out_buf[j] = CHR(b3); j += 1
END
IF pad
c1 = VAL(input_buf[L+1])+1
c2 = VAL(input_buf[L+2])+1
b1 = BSHIFT(B64index[c1], 18)
b2 = BSHIFT(B64index[c2], 12)
n = BOR(b1, b2)
b1 = BSHIFT(n, -16)
out_buf[out_len] = CHR(b1)
IF (in_len > L + 2) AND (input_buf[L + 3] <> '=')
c1 = VAL(input_buf[L + 3])+1
b1 = BSHIFT(B64index[c1], 6)
n = BOR(n, b1)
b1 = BAND(BSHIFT(n, -8), 0FFh)
out_buf[out_len] = CHR(b1)
END
END
RETURN out_buf[1 : out_len]
Build_B64 ROUTINE
!-- build static table
B64index[44] = 62; B64index[45] = 63; B64index[46] = 62; B64index[47] = 62; B64index[48] = 63
LOOP i = 52 TO 61
B64index[i - 3] = i
END
LOOP i = 1 TO 25
B64index[i + 66] = i
END
B64index[96] = 63
LOOP i = 26 TO 51
B64index[i + 72] = i
END