WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

How To
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Base64 encodeing a file


Code that will base64 encode a file

Here is some code that will base64 encode a file so that it can be included in an e-mail. Its not that fast... but it works

For those that don't know. The basic internet e-mail systems can only handle 7bit messages, this means that all e-mail must contain only text. This is a bit of an issue when wanting to send files via e-mail so what E-mail clients do it convert the binary (8bit) file into text (7bit). There are a number of encodeing methods that can be used UUEncode, Base64 and a new one called yEnc. I've used base64 which is described in RFC2045.

To add a file to an e-mail you need to encode the file and add the resulting text to the end of the message and add the following line to the header of the message.

Content-Type: multipart/mixed; boundary="-"
***NOTE*** This is not needed if you are using the Postie Extender. You can use kSendFile to send the file. ***
#DefineFunction Encode(source_file)
   source_file_size = FileSize(source_file)
   source_buffer = BinaryAlloc(source_file_size)
   dest = ""
   BinaryRead(source_buffer, source_file)
   pointer = 0
   For b = 0 To source_file_size By 3
      by1 = 0
      by2 = 0
      by3 = 0
      by1 = BinaryPeek(source_buffer, b)
      If (b+1) < source_file_size Then
         by2 = BinaryPeek(source_buffer, b+1)
         If (b+2) < source_file_size Then
            by3 = BinaryPeek(source_buffer, b+2)
         EndIf
      EndIf
      by4 = by1 >> 2
      by5 = ((by1&3)<<4)|(by2>>4)
      by6 = ((by2&15)<<2)|(by3>>6)
      by7 = by3&63
      dest = StrCat(dest,Encode_6bit(by4),Encode_6bit(by5))
      If (b+1) < source_file_size Then
         dest = StrCat(dest,Encode_6bit(by6))
      Else
         dest = StrCat(dest,"=")
      EndIf
      If (b+2) < source_file_size Then
         dest = StrCat(dest,Encode_6bit(by7))
      Else
         dest = StrCat(dest,"=")
      EndIf
      If StrLen(ItemExtract(-1,dest,@LF))==76 Then dest = StrCat(dest,@CRLF)
   Next
   file_name = ItemExtract(-1,source_file,"\")
   header = StrCat("---",@CRLF,'Content-Type: application/octet-stream; name="',file_name,'"',@CRLF,'Content-Transfer-Encoding: base64',@CRLF,'Content-Disposition: inline; filename="',file_name,'"',@CRLF,@CRLF)
   dest = StrCat(header,dest,@CRLF,"-----",@CRLF)
   BinaryFree(source_buffer)
   Return dest
#EndFunction


#DefineFunction Encode_6bit(bit)
   encode_list = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9,+,/"
   Return ItemExtract(bit+1,encode_list,",")
#EndFunction


source_file = "c:\temp\test.bmp"
dest_file = "c:\temp\mytest.txt"
encoded_result = encode(source_file)
dest_file_handle = FileOpen(dest_file,"WRITE")
IntControl(53,0,0,0,0)
FileWrite(dest_file_handle,encoded_result)
IntControl(53,1,0,0,0)
FileClose(dest_file_handle)

Here are some base64 related udf's:

 #DefineFunction B64GetCookie()
B64Cookie=ArrDimension(256,2)  ; ,0 is to B64  ,1 if from B64
ArrInitialize(B64Cookie,-1)
AUPPER=Char2Num("A")
alower=Char2Num("a")
ZEROChr=Char2Num("0")

for xx=0 to 25
   B64Cookie[xx,0]=Num2Char(AUPPER+xx)
   B64Cookie[xx+26,0]=Num2Char(alower+xx)
next

for xx=52 to 61
   B64Cookie[xx,0]=Num2Char(ZEROChr+xx-52)
next

B64Cookie[62,0]="+"
B64Cookie[63,0]="/"

for xx=0 to 63
    val=Char2Num(B64Cookie[xx,0])
    B64Cookie[val,1]=xx
next
b64Cookie[Char2Num("="),1]=9999  ; flag the = sign

return(B64Cookie)

#EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction Base64BBToClearBB(B64Cookie,b64bb)
   quadsize=BinaryEODGet(b64bb)
   clearbb=BinaryAlloc(quadsize) ; a tad too big.  So...
   qindex=0
   cindex=0
   tcheck=0
   while 1
      if qindex > (quadsize-4) then break
      while 1
         d1=B64Cookie[BinaryPeek(b64bb,qindex+0),1]
         if d1 != -1 then break
      endwhile
      while 1
         d2=B64Cookie[BinaryPeek(b64bb,qindex+1),1]
         if d2 != -1 then break
      endwhile
      while 1
         d3=B64Cookie[BinaryPeek(b64bb,qindex+2),1]
         if d3 != -1 then break
      endwhile
      while 1
         d4=B64Cookie[BinaryPeek(b64bb,qindex+3),1]
         if d4 != -1 then break
      endwhile


      qindex=qindex+4
      tcheck=d1+d2+d3+d4
      if tcheck>=9999 then break
      c1= (d1<<2) | ((d2&48)>>4)
      c2= ((d2&15)<<4) | ((d3&60)>>2)
      c3= ((d3&3)<<6) | d4
      BinaryPoke(clearbb,cindex+0,c1)
      BinaryPoke(clearbb,cindex+1,c2)
      BinaryPoke(clearbb,cindex+2,c3)
      cindex=cindex+3
   endwhile

   if tcheck>=9999
      c1= (d1<<2) | ((d2&48)>>4)
      BinaryPoke(clearbb,cindex,c1)
      cindex=cindex+1
      if d3!=9999
         c2= ((d2&15)<<4) | ((d3&60)>>2)
         BinaryPoke(clearbb,cindex,c2)
         cindex=cindex+1
      endif
      if d4!=9999
         c3= ((d3&3)<<6) | d4
         BinaryPoke(clearbb,cindex,c3)
         cindex=cindex+1
      endif
   endif

   return(clearbb)

#endfunction


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


#DefineFunction Base64BBFromClearBB(B64Cookie,clearbb)
;clearbb contains bytes to be converted into base64 format
;how many triplets
clearbytes=BinaryEODGet(clearbb)
cleartriplets= clearbytes/3
clearremnants= clearbytes mod 3
;if clearremnants !=0 then cleartriplets=cleartriplets+1

b64quads=ClearTriplets
if clearremnants!=0 then b64quads=b64quads+1
b64bytes= b64quads*4
B64BB=BinaryAlloc(b64bytes)

for xx= 1 to cleartriplets
   c1 = BinaryPeek(clearbb,(xx-1)*3+0)
   c2 = BinaryPeek(clearbb,(xx-1)*3+1)
   c3 = BinaryPeek(clearbb,(xx-1)*3+2)

   d1 =                      c1 >> 2
   d2 = ( (c1 &  3) << 4) | (c2 >> 4)
   d3 = ( (c2 & 15) << 2) | (c3 >> 6)
   d4 = ( (c3 & 63)     )
   quad=strcat(B64Cookie[d1,0],B64Cookie[d2,0],B64Cookie[d3,0],B64Cookie[d4,0])
   BinaryPokeStr(b64BB,(xx-1)*4,quad)

next xx


switch clearremnants
   case 1
       c1=BinaryPeek(clearbb,(cleartriplets)*3+0)
       d1 =                      c1 >> 2
       d2 = ( (c1 &  3) << 4) 
       quad=strcat(B64Cookie[d1,0],B64Cookie[d2,0],"==")
       continue
   case 2
       c1=BinaryPeek(clearbb,(cleartriplets)*3+0)
       c2 = BinaryPeek(clearbb,(cleartriplets)*3+1)
       d1 =                      c1 >> 2
       d2 = ( (c1 &  3) << 4) | (c2 >> 4)
       d3 = ( (c2 & 15) << 2)
       quad=strcat(B64Cookie[d1,0],B64Cookie[d2,0],B64Cookie[d3,0],"=")
       continue
   case 1
   case 2
      BinaryPokeStr(b64BB,(cleartriplets)*4,quad)
endswitch



return(b64BB)
#EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction Base64StringFromClearString(B64Cookie,clearstring)
  s=Strlen(clearstring)
  bb=BinaryAlloc(s)
  BinaryPokeStr(bb,0,clearstring)
  b64bb=Base64BBFromClearBB(B64Cookie,bb)
  s=BinaryPeekStr(b64bb,0,BinaryEODGet(b64bb))
  BinaryFree(bb)
  BinaryFree(b64bb)
  return(s)
#EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#DefineFunction Base64StringToClearString(B64Cookie,b64String)
  s=Strlen(b64String)
  bb=BinaryAlloc(s)
  BinaryPokeStr(bb,0,b64String)
  clearbb=Base64BBToClearBB(B64Cookie,bb)
  s=BinaryPeekStr(clearbb,0,BinaryEODGet(clearbb))
  BinaryFree(bb)
  BinaryFree(clearbb)
  return(s)
#EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sample usage
; Step 1 Call b64GetCookie to get B64Cookie first

B64Cookie=B64GetCookie()

;Then use the various functions

test="A quick brown fox orders a triple mocha."

b64test=Base64StringFromClearString(B64Cookie,test)

Message(test,b64test)

test2=Base64StringToClearString(B64Cookie,b64test)
Message(test,test2)

exit



Article ID:   W15956
File Created: 2004:03:30:15:42:04
Last Updated: 2004:03:30:15:42:04