'Author: James Moneypenny 'Source: http://www.powerbasic.com/support/forums/Forum6/HTML/001799.html ' 'In an effort to speed up my base64 encoding for file attachments and e-mail. 'I set out to figure out the fastest way I could encode Base64 using PowerBasic. 'The following is a small test program that I used to test four different routines. ' 'The first base64 function called called was posted by Dave Navarro (modified to encode Base64 only)), 'being mostly programmed in inline assembler I figured it would be the fastest at encoding the test data. ' 'The second base64 function called is the same as the first but I modified the outbuf string to be 'preallocated at the start of the function and modified the routine to step through the 'inbuff instead of stripping and recreating inbuff on each iteration of the loop. ' 'The third base64 function called is my code that uses no assembler and basically (no pun intended) 'performs the encoding the same as Dave's code. ' 'The fourth base64 function called is my code and it is the same as the third function, but it uses pointer instead 'of the mid$ statement to step through and set values in the variable I use to output 'the encoded data. ' 'The following has helped me with some of my programming issues and source code posted to this forum '(such as the many posts by Dave and many others.) ' 'Please feel free to use the following code I posted as you see fit, but respect the 'work of code posted by others. '---------------------------------------------------------------------------- ' Convert a file to MIME text (Base64 Encoded) for PB/DLL or PB/CC ' by Dave Navarro (dave@powerbasic.com) ' FUNCTION encode_base64_Dave_UnModified$(d$) LOCAL Enc AS STRING * 64 LOCAL b AS ASCIIZ * 4 LOCAL InBuff AS STRING LOCAL OutBuff AS STRING REGISTER i AS LONG Enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" InBuff=d$ OutBuff = "" WHILE LEN(InBuff) b = LEFT$(InBuff, 3) ! mov AL, b[0] ! shr AL, 2 ! movzx i, AL OutBuff = OutBuff + MID$(Enc, i+1, 1) ! mov AL, b[1] ! mov AH, b[0] ! shr AX, 4 ! and AL, &H3F ! movzx i, AL OutBuff = OutBuff + MID$(Enc, i+1, 1) IF LEN(InBuff) = 1 THEN OutBuff = OutBuff + "==" EXIT DO END IF ! mov AL, b[2] ! mov AH, b[1] ! shr AX, 6 ! and AL, &H3F ! movzx i, AL OutBuff = OutBuff + MID$(Enc, i+1, 1) IF LEN(InBuff) = 2 THEN OutBuff = OutBuff + "=" EXIT DO END IF ! mov AL, b[2] ! and AL, &H3F ! movzx i, AL OutBuff = OutBuff + MID$(Enc, i+1, 1) InBuff = MID$(InBuff, 4) WEND function=OutBuff END FUNCTION '---------------------------------------------------------------------------- ' Convert a file to MIME text (Base64 Encoded) for PB/DLL or PB/CC ' by Dave Navarro (dave@powerbasic.com) ' FUNCTION encode_base64_Dave_Modified$(d$) LOCAL Enc AS STRING * 64 LOCAL b AS ASCIIZ * 4 LOCAL InBuff AS STRING LOCAL OutBuff AS STRING REGISTER i AS LONG Enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" InBuff=d$ 'OutBuff = "" OutBuff=space$(len(InBuff)*2) 'WHILE LEN(InBuff) for c_count&=1 to LEN(InBuff) step 3 b = mid$(InBuff,c_count&, 3) ! mov AL, b[0] ! shr AL, 2 ! movzx i, AL outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)=MID$(Enc, i+1, 1) 'OutBuff = OutBuff + MID$(Enc, i+1, 1) ! mov AL, b[1] ! mov AH, b[0] ! shr AX, 4 ! and AL, &H3F ! movzx i, AL outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)=MID$(Enc, i+1, 1) 'OutBuff = OutBuff + MID$(Enc, i+1, 1) IF LEN(b) = 1 THEN outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)="==" 'OutBuff = OutBuff + "==" EXIT for END IF ! mov AL, b[2] ! mov AH, b[1] ! shr AX, 6 ! and AL, &H3F ! movzx i, AL outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)=MID$(Enc, i+1, 1) 'OutBuff = OutBuff + MID$(Enc, i+1, 1) IF LEN(b) = 2 THEN outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)="=" 'OutBuff = OutBuff + "=" EXIT for END IF ! mov AL, b[2] ! and AL, &H3F ! movzx i, AL outbuff_counter&=outbuff_counter&+1 mid$(OutBuff,outbuff_counter&,1)=MID$(Enc, i+1, 1) 'OutBuff = OutBuff + MID$(Enc, i+1, 1) '''''InBuff = MID$(InBuff, 4) next function=mid$(OutBuff,1,outbuff_counter&) END FUNCTION FUNCTION encode_base64_Mine_using_mid$(d$) DIM hold_char1 AS WORD DIM hold_char2 AS WORD DIM hold_char_temp AS WORD DIM hold_6bit_char AS BYTE DIM dict_pointer AS BYTE pointer DIM d1_pointer AS BYTE pointer DIM d2_pointer AS BYTE pointer c$=space$(len(d$)*2) dict$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" dict_pointer=strptr(dict$) d1_pointer=strptr(d$) d2_pointer=strptr(d$) static ii as long xx&=(LEN(d$))-(LEN(d$) MOD 3) FOR x&=1 TO xx& STEP 3 hold_char1=@d1_pointer[x&]+(@d1_pointer[x&-1])*256 hold_char2=@d1_pointer[x&+1]+(@d1_pointer[x&])*256 hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 'c$=c$+chr$(@dict_pointer[hold_char_temp]) mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,4 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,10 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) NEXT x& x_mod&=(LEN(d$) MOD 3) IF x_mod&=1 THEN hold_char1=CVWRD(CHR$(0)+MID$(d$,xx&+1,1)) hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) c_counter&=c_counter&+1 'c$=c$+"==" mid$(c$,c_counter&,1)="=" c_counter&=c_counter&+1 'c$=c$+"==" mid$(c$,c_counter&,1)="=" END IF IF x_mod&=2 THEN hold_char1=CVWRD(MID$(d$,xx&+2,1)+MID$(d$,xx&+1,1)) hold_char2=CVWRD(CHR$(0)+MID$(d$,xx&+2,1)) hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,4 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 mid$(c$,c_counter&,1)=chr$(@dict_pointer[hold_char_temp]) c_counter&=c_counter&+1 'c$=c$+"=" mid$(c$,c_counter&,1)="=" END IF FUNCTION=mid$(c$,1,c_counter&) END FUNCTION FUNCTION encode_base64_Mine_using_pointer$(d$) DIM hold_char1 AS WORD DIM hold_char2 AS WORD DIM hold_char_temp AS WORD DIM hold_6bit_char AS BYTE DIM dict_pointer AS BYTE pointer DIM d1_pointer AS BYTE pointer DIM d2_pointer AS BYTE pointer DIM char_pointer AS BYTE pointer c$=space$(len(d$)*2) char_pointer=strptr(c$) dict$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" dict_pointer=strptr(dict$) d1_pointer=strptr(d$) d2_pointer=strptr(d$) static ii as long xx&=(LEN(d$))-(LEN(d$) MOD 3) FOR x&=1 TO xx& STEP 3 hold_char1=@d1_pointer[x&]+(@d1_pointer[x&-1])*256 hold_char2=@d1_pointer[x&+1]+(@d1_pointer[x&])*256 hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 'c$=c$+chr$(@dict_pointer[hold_char_temp]) @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,4 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,10 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] NEXT x& x_mod&=(LEN(d$) MOD 3) IF x_mod&=1 THEN hold_char1=CVWRD(CHR$(0)+MID$(d$,xx&+1,1)) hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] c_counter&=c_counter&+1 'c$=c$+"=" @char_pointer[c_counter&-1]=asc("=") c_counter&=c_counter&+1 'c$=c$+"=" @char_pointer[c_counter&-1]=asc("=") END IF IF x_mod&=2 THEN hold_char1=CVWRD(MID$(d$,xx&+2,1)+MID$(d$,xx&+1,1)) hold_char2=CVWRD(CHR$(0)+MID$(d$,xx&+2,1)) hold_char_temp=hold_char1 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char1 SHIFT LEFT hold_char_temp,6 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] hold_char_temp=hold_char2 SHIFT LEFT hold_char_temp,4 SHIFT RIGHT hold_char_temp,10 c_counter&=c_counter&+1 @char_pointer[c_counter&-1]=@dict_pointer[hold_char_temp] c_counter&=c_counter&+1 'c$=c$+"=" @char_pointer[c_counter&-1]=asc("=") END IF FUNCTION=mid$(c$,1,c_counter&) END FUNCTION Function PBMain() as long cls Print "Base64 Using 100000 Characters......" Print hold_timer@@=timer c$=space$(100000) c$=encode_base64_Dave_UnModified$(c$) print "Test String::";Mid$(c$,99990,10);Len(c$) Print "End timer:";Timer print "Timer Diff:";round(timer-hold_timer@@,4) print '********************************************************************************** Print "Start timer:";timer hold_timer@@=timer c$=space$(100000) c$=encode_base64_Dave_Modified$(c$) print "Test String::";Mid$(c$,99990,10);Len(c$) Print "End timer:";Timer print "Timer Diff:";round(timer-hold_timer@@,4) print '********************************************************************************** Print "Start timer:";timer hold_timer@@=timer c$=space$(100000) c$=encode_base64_Mine_using_mid$(c$) print "Test String::";Mid$(c$,99990,10);Len(c$) Print "End timer:";Timer print "Timer Diff:";round(timer-hold_timer@@,4) print '********************************************************************************** Print "Start timer:";timer hold_timer@@=timer c$=space$(100000) c$=encode_base64_Mine_using_pointer$(c$) print "Test String::";Mid$(c$,99990,10);Len(c$) Print "End timer:";Timer print "Timer Diff:";round(timer-hold_timer@@,4) print end function