Delphi嵌入汇编版Base64编码过程,采用有效位为12位的16位码表 感谢 DelphiGuy 于 2010-10-08 17:27:37 给出的提醒 unit uEncoder3To4_12BitsCoderTable; { 2010-09-28 创建 by unsigned(僵哥) } interface procedure Base64EncodeEx(InputCount: Integer; const Input: Pointer; Output: Pointer); assembler; implementation var B64Table:array[0..65535] of Word; procedure Base64EncodeEx(InputCount: Integer; const Input: Pointer; Output: Pointer); assembler; asm //感谢 DelphiGuy 于 2010-10-08 17:27:37 给出的提醒,防止 "ECX and EDX = 0" 的情况发生 { TEST ECX, EDX // Input = Nil or Output = Nil ? jz @ret // if (Input = Nil) or (Output = Nil) then Exit; } TEST ECX, ECX jz @ret TEST EDX, EDX jz @ret push esi //saving Registers push edi push ebx push ebp lea ebp, [B64Table] //load B64-CodeTable-16Bits mov esi, edx //ESI := Input mov edi, ecx //EDI := Output xor edx, edx mov ecx, 3 div ecx //EAX := InputCount div 3, EDX := InputCount mod 3 xor ebx,ebx //Clear EBX dec esi test eax, eax //InputCount div 3 = 0 ? jz @next //if InputCount div 3 = 0 then Do Next with (InputCount mod 3) Bytes mov ecx, [esi + 1] //ECX := 0x44332211 , Bits = 44444444 33333333 22222222 11111111 bswap ecx //ECX := 0x11223344 , Bits = 11111111 22222222 33333333 44444444 shr ecx, 8 //ECX := 0x00112233, valid-Bits: 00000000 11111111 22222222 33333333 mov bx, cx //BX := 0x2233, , Bits = 22222222 33333333, valid-Bits: 2222 33333333 mov bx, [ebp + ebx * 2] //BX := CodeTable[Bits:00000000 00000000 00002222 33333333] mov [edi+2], bx //PWord(@Output[2])^ := BX shr ecx, 12 //First 12-bits, Bits = 00000000 0000000 00001111 11112222 mov bx, cx //BX := Bits:00001111 11112222 mov bx, [ebp + ebx * 2] //BX := CodeTable[Bits:00000000 00000000 00001111 11112222] mov [edi], bx //PWord(@Output[0])^ := BX add edi, 4 //Inc(Output, 4) add esi, 3 //Inc(Input, 3) Dec EAX jz @next //Dec EAX, if EAX = 0 then Goto @next @loop: mov ecx, [esi] //ECX := 0x66554433 , Bits = 66666666 55555555 44444444 33333333 bswap ecx //ECX := 0x33445566 , Bits = 33333333 44444444 55555555 66666666 //valid-Bits: 00000000 44444444 55555555 66666666 mov bx, cx //BX := 0x5566, Bits = 55555555 66666666, valid-Bits: 5555 66666666 mov bx, [ebp + ebx * 2] //BX := CodeTable[Bits:00000000 00000000 00005555 66666666] mov [edi+2], bx //PWord(@Output[2])^ := BX shr ecx, 12 //First 12-bits, Bits = 00000000 0000000 00004444 444455555 mov bx, cx //BX := Bits:00004444 44445555 mov bx, [ebp + ebx * 2] //BX := CodeTable[Bits:00000000 00000000 00004444 44445555] mov [edi], bx //PWord(@Output[0])^ := BX add edi,4 //Inc(Output, 4) add esi,3 //Inc(Input, 3) Dec EAX jnz @loop //Dec EAX, if EAX <> 0 then Goto @Loop @next: dec edx // EDX := (InputCount mod 3) - 1 jz @OneByte // if EDX = 0 then GOTO One-Byte jns @TwoBytes // if EDX <> -1 then GOTO Two-Bytes pop ebp pop ebx pop edi pop esi @ret: ret //Last two-Bytes @TwoBytes: mov bx, [esi + 1] //Bits: 22222222 11111111 xchg bh, bl //Bits: 11111111 22222222 mov ah, bl mov ax, [ebp + eax * 2] //AX := CodeTable[Bits:00000000 00000000 00002222 00000000] mov [edi + 2], ax shr ebx, 4 //Bits: 00000000 00000000 00001111 11112222 mov ax, [ebp + ebx * 2] //AX := CodeTable[Bits:00000000 00000000 00001111 11112222] mov [edi], ax mov Byte ptr [edi + 3], 61 //'=' pop ebp pop ebx pop edi pop esi ret //Last one-Byte @OneByte: mov al, Byte Ptr [esi + 1] // Bits: 11111111 lea eax, [eax * 8] // eax * 8 = (eax shl 4) / 2 mov bx, [ebp + eax * 4] // eax * 4 = (eax shl 1) * 2, Bits: 00001111 11110000 // BX := CodeTable[Bits:00000000 00000000 00001111 11110000] mov [edi], bx mov Byte ptr [edi + 2], 61 //'=' mov Byte ptr [edi + 3], 61 //'=' pop ebp pop ebx pop edi pop esi end; var i: Integer; const Base64_Chars: array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; //0123456789012345678901234567890123456789012345678901234567890123 //0 1 2 3 4 5 6 initialization for I := 0 to 65536 - 1 do begin B64Table[I] := (Word(Byte(Base64_Chars[I and $3f])) shl 8 ) or (Word(Byte(Base64_Chars[(I shr 6) and $3f]))); end; end.