REM
REM Demo implementing BASE64 encoder
REM
REM March 2009 - PvE.
REM Revised November 2009.
REM

REM Get the separate arguments
SPLIT ARGUMENT$ BY " " TO arg$ SIZE dim

IF dim < 2 THEN
    PRINT "Usage: b64enc <string>"
    END
ENDIF

REM Get the string to convert
dat$ = CHOP$(MID$(ARGUMENT$, INSTR(ARGUMENT$, " ")))

REM the LET statement is optional
CONST BASE64$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

WHILE LEN(dat$) > 0 DO

    REM Find ASCII values
    IF LEN(dat$) EQ 1 THEN
        byte1 = ASC(MID$(dat$, 1, 1))
        byte2 = 0
        byte3 = 0
    ELIF LEN(dat$) EQ 2 THEN
        byte1 = ASC(MID$(dat$, 1, 1))
        byte2 = ASC(MID$(dat$, 2, 1))
        byte3 = 0
    ELSE
        byte1 = ASC(MID$(dat$, 1, 1))
        byte2 = ASC(MID$(dat$, 2, 1))
        byte3 = ASC(MID$(dat$, 3, 1))
    ENDIF

    REM Create Base64 values
    base1 = byte1 / 4
    base2 = (byte1 & 3) * 16 + (byte2 & 240) / 16
    base3 = (byte2 & 15) * 4 + (byte3 & 192) / 64
    base4 = byte3 & 63

    REM Find Base64 characters
    IF LEN(dat$) EQ 1 THEN
        enc$ = CONCAT$(enc$, MID$(BASE64$, base1 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base2 + 1, 1))
        enc$ = CONCAT$(enc$, "==")
        dat$ = ""
    ELIF LEN(dat$) EQ 2 THEN
        enc$ = CONCAT$(enc$, MID$(BASE64$, base1 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base2 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base3 + 1, 1))
        enc$ = CONCAT$(enc$, "=")
        dat$ = ""
    ELSE
        enc$ = CONCAT$(enc$, MID$(BASE64$, base1 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base2 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base3 + 1, 1))
        enc$ = CONCAT$(enc$, MID$(BASE64$, base4 + 1, 1))
        dat$ = RIGHT$(dat$, LEN(dat$) - 3)
    ENDIF

WEND

PRINT enc$