Base64 decoding function

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
1 Like