Base64 Decoder
Root / Programming Questions / [.]
DevinF06Created:
VAR BASE64$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 'Converting a base 64 character in to a number from 0 to 63: '(This isn't the most efficient method but it's the simplest) DEF READ_B64_DIGIT(D$) VAR D=INSTR(BASE64$,D$[I]) IF D<0 THEN PRINT "Illegal character found" BEEP STOP ENDIF RETURN D END DEF DECODE_B64(B64$) IF LEN(B64$) MOD 4 THEN PRINT "Length must be a multiple of 4" BEEP STOP ENDIF DIM RET[0] VAR TEMP,TEMP_SIZE VAR I FOR I=0 TO LEN(B64$)-1 IF B64$[I]=="=" THEN BREAK TEMP=TEMP<<6 OR READ_B64_DIGIT(B64$[I]) INC TEMP_SIZE,6 IF TEMP_SIZE>=8 THEN DEC TEMP_SIZE,8 PUSH RET,TEMP>>TEMP_SIZE AND 255 ENDIF NEXT RETURN RET ENDBasically the way this works is that each base 64 character contains 6 bits of information, and you need to output a list of 8-bit values. So it reads the base 64 string, and keeps track of the 6 bits from each character. When it has at least 8 bits, it takes the oldest 8 bits and adds them to the output array.
I am too slow. Do you want my example, it has a encoder and a decoder? Well, just in case and so my effort wasn't in vain, here it is. Please excuse any type-os as I manually retyped this in. If you wanted it to work with arrays instead, it shouldn't be too hard to adapt. So, what do you need Base64 for? I hope I didn't just do your homework.
OPTION STRICT VAR BASE64_INDEX$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" VAR TEST$ = "Hello world! This is a test of the Base64 Encoder / Decoder." + CHR$(10) + "I used " + CHR$(34) + "http://en.wikipedia.org/wiki/Base_64" + CHR$(34) + " as a implementation reference. It will encode / decode string." VAR RESULT$ = "" RESULT$ = ENCODE_BASE64(TEST$) PRINT RESULT$ RESULT$ = DECODE_BASE64(RESULT$) PRINT RESULT$ END DEF ENCODE_BASE64(VALUE$) VAR MAX_WIDTH = 40 VAR LINE_LEN = 0 VAR MSG_LEN = LEN(VALUE$) VAR RET$ = "" VAR I, J, IDX VAR TEMP$, WORK$ = "" FOR 1 = 0 TO MSG_LEN - 1 STEP 3 WORK$ = WORK$ + BIN$(ASC(MID$(VALUE$, I, 1)), 8) IF I + 1 < MSG_LEN THEN WORK$ = WORK$ + BIN$(ASC(MID$(VALUE$, I + 1, 1)), 8) ENDIF IF I + 2 < MSG_LEN THEN WORK$ = WORK$ + BIN$(ASC(MID$(VALUE$, I + 2, 1)), 8) ENDIF FOR J = 0 TO 3 IF LEN(WORK$) >= 6 THEN TEMP$ = LEFT$(WORK$, 6) WORK$ = MID$(WORK$, 6, LEN(WORK$) - 6) IDX = VAL("&B" + TEMP$) RET$ = RET$ + MID$(BASE64_INDEX$, IDX, 1) ELSEIF LEN(WORKI$) >= 1 THEN TEMP$ = LEFT$(WORK$ + "000000", 6) WORK$ = "" IDX = VAL("&B" + TEMP$) RET$ = RET$ + MID$(BASE64_INDEX$, IDX, 1) ELSE RET$ = RET$ + "=" ENDIF LINE_LEN = LINE_LEN + 1 IF LINE_LEN >= MAX_WIDTH THEN LINE_LEN = 0 RET$ = RET$ + CHR$(10) 'Enter key ENDIF NEXT J NEXT i RETURN RET$ END DEF DECODE_BASE64(VALUE$) VAR I, J, CH$, RET$ = "", WORK$ = "" VAR TEMP$, MAX_LEN IF RIGHT$(VALUE$, 2) = "==" THEN MAX_LEN = LEN(VALUE$) - 2 IF RIGHT$(VALUE$, 1) = "=" THEN MAX_LEN = LEN(VALUE$) - 1 ELSE MAX_LEN = LEN(VALUE$) ENDIF FOR I = 0 TO MAX_LEN - 1 CH$ = MID$(VALUE$, I, 1) J = INSTR(BASE64_INDEX$, CH$) IF J >= 0 THEN WORK$ = WORK$ + BIN$(J, 6) ENDIF WHILE LEN(WORK$) >= 8 TEMP$ = LEFT$(WORK$, 8) WORK$ = MID$(WORK$, 8, LEN(WORK$) - 8) RET$ = RET$ + CHR$(VAL("&B" + TEMP$)) WEND NEXT i RETURN RET$ ENDAgain like the comment at the top of the code says, wikipedia is your friend. https://en.wikipedia.org/wiki/Base_64