; BASE64编码是邮件加密协议的必用算法,实际上就是一个简单的字节置换
; 首先是将原字符串按6 bits 分组,高2位加0作为一个字节然后查找如下的
; 码表获得加密字符.原文字符若不为3的倍数,用0补足参与运算,最后要把全
; 0字节置换为"=",具体算法如下代码所示:
; 可以采用查表法处理,但同样的问题是,那不适我喜欢的方式,让我聪明的程序
; 来干这玩意吧.
; 码表如下:
; Value Encoding Value Encoding Value Encoding Value Encoding
; 0 A 17 R 34 i 51 z
; 1 B 18 S 35 j 52 0
; 2 C 19 T 36 k 53 1
; 3 D 20 U 37 l 54 2
; 4 E 21 V 38 m 55 3
; 5 F 22 W 39 n 56 4
; 6 G 23 X 40 o 57 5
; 7 H 24 Y 41 p 58 6
; 8 I 25 Z 42 q 59 7
; 9 J 26 a 43 r 60 8
; 10 K 27 b 44 s 61 9
; 11 L 28 c 45 t 62 +
; 12 M 29 d 46 u 63 /
; 13 N 30 e 47 v
; 14 O 31 f 48 w (pad) =
; 15 P 32 g 49 x
; 16 Q 33 h 50 y
include '%fasinc%/win32as.inc'
.data
en_1 db "Sun Bird!!!"
en1.size=$-en_1
fmt db "ENC length=%d DECode length=%d",0
buf2 rb 256
buf3 rb 256
buf rb 256
zTit db "By Hume 2K2",0
.code
StArT:
mov esi,en_1
mov edi,buf
mov ecx,en1.size
call base64_enc
invokeMessageBox,0,buf,zTit,0
mov edi,buf
call my_strlen
mov esi,buf
mov edi,buf3
call base64_dec
invokeMessageBox,0,buf3,zTit,0
invokewsprintf,buf2,fmt,enc.size,b64.dcode.size
invokeMessageBox,0,buf2,zTit,0
invokeExitProcess,0
my_strlen: ;edi->stringz ecx and eax and edi altered...
xor eax,eax
or ecx,-1
repnz scasb
neg ecx
dec ecx
dec ecx
ret
;IN : esi=src_begin ecx=len>0
;OUT: edi=buf contains encoded strings
;pure code lines=55 size=112 bytes
base64_enc:
xor eax,eax
gen_base64:
xor ebx,ebx
lodsb
shl eax,8
loop @@2
shl eax,8
inc ebx
inc ebx
jmp @@_
@@2:
lodsb
shl eax,8
loop @@3
inc ebx
jmp @@_
@@3:
lodsb
dec ecx
@@_:
push ecx
push 4
pop ecx
push ecx
@@:
rol edx,8
mov dl,al
and dl,00111111B
shr eax,6
loop @B
pop ecx
call edx2_b64
xchg eax,edx
stosd
xchg eax,edx
pop ecx
or ecx,ecx
jnz gen_base64
mov ecx,ebx
sub edi,ecx
mov al,"="
rep stosb
ret
edx2_b64:
cmp dl,62
jae dl_62_63
cmp dl,51
ja digit_0_9
add dl,'A'
cmp dl,'Z'
jbe @F
add dl,'a'-'Z'-1
@@:
jmp rotate_edx
digit_0_9:
add dl,30h-52
jmp rotate_edx
dl_62_63:
sub dl,62
shl dl,2
add dl,43
rotate_edx:
rol edx,8
loop edx2_b64
ret
enc.size=$-base64_enc
;IN :ecx=length esi=string edi=outBUF
;OUT:buf=decompress data edx=actual len
;pure code 49 lines and 101 bytes long
;many regs are altered.(you can count it!)
base64_dec:
push edi
shr ecx,2
mov edx,ecx
imul edx,edx,3
next_dword:
push ecx
lodsd
push 4
pop ecx
push ecx
call eax_b64_2_org
pop ecx ;ecx=4!
xor ebx,ebx
bswap eax
@@:
shl eax,2
shld ebx,eax,6
shl eax,6
loop @B
mov eax,ebx
bswap eax
shr eax,8
stosb
shr eax,8
stosw
pop ecx
loop next_dword
pop edi
mov byte [edi+edx],0
ret
eax_b64_2_org:
cmp al,'='
jne @F
xor al,al
dec edx
@@:
cmp al,'/'
ja is_digit_0_9
sub al,'+'
shr al,2
add al,62
jmp rotate_eax
is_digit_0_9:
cmp al,'9'
ja is_alphabet
add al,52-'0'
jmp rotate_eax
is_alphabet:
sub al,'A'
cmp al,25
jbe rotate_eax
sub al,6
rotate_eax:
rol eax,8
loop eax_b64_2_org
ret
b64.dcode.size=$-base64_dec
.end StArT