News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Base64 Encode and Decode

Started by Robert Collins, September 18, 2007, 07:01:52 PM

Previous topic - Next topic

Robert Collins

Whoo! I haven't been here is such a long time I even forgot what I was doing when I was here last. Oh well, on with the new stuff.

I am working on a Email client, very similar to Outlook Express, and have got it to work in all respects just like Outlook except for one thing left to do. Up till now I wasn't really concerned about attacnments, especially pictures, but now I want to add that feature to the application. I know that attachments are encoded in Base64 when sent to a POP3 server and decoded using Base64 when recieved from a SMTP server. I know what Base64 is but I don't have the slightest idea how to code it(mainly because I have no idea of what the algorithm is) so I am looking for a good module written in Assembly that I can turn into a DLL that will recieve unencoded data and get back the encoded data and can recieve encoded data and return the unencoded data back. The mail program is written in Visual Basic (I wouldn't even think about trying to write this program in Assembly because it is way beyond my experience to do so) and I have found some OK Base64 Encoder\Decoder application already coded in VB and they are OK for small files but totally break down on large files.

Does anyone know where I might find some assembly stuff on this matter? Any help would be highly appreciated. 

ecube

I didn't write this, but enjoy


base64_decode proto :DWORD,:DWORD
base64_encode proto :DWORD,:DWORD,:DWORD
encodeblock   proto :DWORD,:DWORD,:DWORD
.data
base64 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',0

.code

base64_decode proc uses ecx ebx edi esi lpIn:DWORD, dwLen:DWORD
LOCAL InBuf:DWORD
LOCAL Len:DWORD

or dwLen, 0
jz @enddecode

mov Len, 0
mov esi, lpIn
mov edi, esi

@next4bytes:
xor ecx, ecx

.while ecx < 4
lodsb
.if al >= 'A' && al <= 'Z'
sub al, 'A'
.elseif al >='a' && al <= 'z'
sub al, 71
.elseif al >='0' && al <= '9'
add al, 4
.elseif al == '/'
add al, 16
.elseif al == '+'
add al, 19
.elseif al == '='
xor al, al
.else
jmp @f
.endif
stosb
inc ecx
@@:
inc Len
mov eax, Len
cmp eax, dwLen
ja @enddecode
.endw

@@:

mov edx, esi
xor ebx, ebx
;xor eax, eax
mov ecx, 4
sub edi, ecx
mov esi, edi ;save esi

@@:
lodsb
shl ebx, 6
or bl, al
dec ecx
jnz @b

mov eax, ebx
shl eax, 8
bswap eax
stosd
dec edi
mov esi, edx ;restore esi

mov eax, Len
cmp eax, dwLen
jb @next4bytes

@enddecode:
ret

base64_decode endp


base64_encode proc uses ecx ebx edi esi lpBuffer:DWORD, lpOut:DWORD, dwLen:DWORD
LOCAL Len:DWORD
LOCAL BufIn[4]:BYTE
LOCAL BufOut[5]:BYTE

mov eax, lpOut
and byte ptr [eax], 0

mov esi, lpBuffer
mov Len, 0

@@:
lea edi, BufIn

xor ecx, ecx
.while ecx < 3
mov eax, Len
.if eax < dwLen
lodsb
stosb
.else
jmp @endoffile
xor al, al
stosb
.endif
inc ecx
inc Len
.endw

@endoffile:
lea eax, BufIn
lea ebx, BufOut
invoke encodeblock, eax, ebx, ecx
and byte ptr [ebx+4], 0
invoke lstrcat, lpOut, ebx
mov eax, Len
cmp eax, dwLen
jb @b
ret
base64_encode endp

encodeblock proc lpIn:DWORD, lpOut:DWORD, dwLen:DWORD
LOCAL InBuf:DWORD
pushad

mov esi, lpIn

mov [InBuf], 0 ;reset
lea edi, InBuf
mov ecx, dwLen
rep movsb
mov eax, [InBuf]
bswap eax
shr eax, 8

mov edi, lpOut

mov ebx, eax

mov cl, 18
mov edx, 111111000000000000000000b

@@:
mov eax, ebx
and eax, edx
shr eax, cl
mov al, byte ptr [base64][eax]
stosb
sub cl, 6
shr edx, 6
jnz @b

mov ecx, dwLen
cmp ecx, 1
ja @f
mov word ptr [edi-2], '='
@@:
cmp ecx, 2
ja @f
mov word ptr [edi-1], '='
@@:
popad
ret

encodeblock endp