decard
Joined: 11 Sep 2003
Posts: 1092
Location: Poland
|
Hi friends,
Here are two simple functions that perform base64 coding and decoding. Something useful when you are coding email client for example
Both functions take the same arguments: pointer to source, source size, and pointer to output buffer. Both return output size in eax (though it can be easily calculated).
base64_table db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
db "abcdefghijklmnopqrstuvwxyz"
db "0123456789+/"
proc base64_encode, .source,.src_size,.out_buf
begin
push ecx edx esi edi
mov esi,[.source]
mov edi,[.out_buf]
mov ecx,[.src_size]
.loop:
mov edx,[esi]
cmp ecx,3
jae .remainder_ok
and edx,0xffff
cmp ecx,2
jae .remainder_ok
and edx,0xff
.remainder_ok:
bswap edx
mov eax,edx
shr eax,26
and eax,111111b
mov al,[base64_table+eax]
mov [edi],al
inc edi
mov eax,edx
shr eax,20
and eax,111111b
mov al,[base64_table+eax]
mov [edi],al
inc edi
dec ecx
jz .r2
mov eax,edx
shr eax,14
and eax,111111b
mov al,[base64_table+eax]
mov [edi],al
inc edi
dec ecx
jz .r1
mov eax,edx
shr eax,8
and eax,111111b
mov al,[base64_table+eax]
mov [edi],al
inc edi
add esi,3
dec ecx
jnz .loop
mov byte[edi],0
return
.r2:
mov byte[edi],'='
inc edi
.r1:
mov byte[edi],'='
inc edi
mov byte[edi],0
sub edi,[.out_buf]
mov eax,edi ; return output size in eax
pop edi esi edx ecx
return
endp
proc base64_decode, .source,.src_size,.out_buf
.decode_table rb 0x100
begin
push ebx ecx edx esi edi
xor eax,eax
mov ebx,63
.make_table:
mov al,[base64_table+ebx]
mov [.decode_table+eax],bl
dec ebx
jns .make_table
mov [.decode_table+'='],0
mov esi,[.source]
mov ecx,[.src_size]
mov edi,[.out_buf]
xor ebx,ebx
; xor eax,eax ; not needed - eax was xored before
.load_dword:
mov edx,[esi]
bswap edx
add esi,4
mov al,dl
mov al,byte[.decode_table+eax]
shrd ebx,eax,6
shr edx,8
mov al,dl
mov al,byte[.decode_table+eax]
shrd ebx,eax,6
shr edx,8
mov al,dl
mov al,byte[.decode_table+eax]
shrd ebx,eax,6
shr edx,8
mov al,dl
mov al,byte[.decode_table+eax]
shrd ebx,eax,6
bswap ebx
mov [edi],ebx
add edi,3
sub ecx,4
js .exit_loop ; this jump should be never taken
jnz .load_dword ; (src_size should be a multiple of four)
.exit_loop:
mov byte[edi],0
inc edi
sub edi,[.out_buf]
mov eax,edi ; return output size in eax
pop edi esi edx ecx ebx
return
endp
regards
|