; 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