核心提示:由于目前编写的代码最终都是在服务器上运行的,所以有时候也会有点变态地追求所谓的性能问题,因此希望各位能够贡献点资源上来,先谢过。先发一个比较变态的单元,其实也不是什么好东西,只是一个采用了16bit码...
由于目前编写的代码最终都是在服务器上运行的,所以有时候也会有点变态地追求所谓的性能问题,因此希望各位能够贡献点资源上来,先谢过。先发一个比较变态的单元,其实也不是什么好东西,只是一个采用了16bit码表(有效位为12位)的Base64编码过程,之所以变态在于码表需要占用128KB的内存,当然在目前的系统当中这已经不是什么问题...unit uEncoder3To4_12BitsCoderTable;
{
2010-09-28 创建 by unsigned(僵哥)
}
interface
procedure Base64EncodeEx(InputCount: Integer; const Input: Pointer; Output: Pointer); assembler;
function GetSizeCoder3To4(InputCount: Integer): Integer; inline;
implementation
var
B64Table:array[0..65535] of Word;
function GetSizeCoder3To4(InputCount: Integer): Integer; inline;
begin
Result := (InputCount+2) div 3 * 4
end;
procedure Base64EncodeEx(InputCount: Integer; const Input: Pointer; Output: Pointer); assembler;
asm
TEST ECX, EDX // Input = Nil or Output = Nil ?
jz @end // if (Input = Nil) or (Output = Nil) then Exit;
Test EAX, EAX // InputCount = 0?
jz @end // if InputCount = 0 then Exit;
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
mov edx, 0
mov ecx, 3
div ecx //EAX := InputCount div 3, EDX := InputCount mod 3
mov ecx, eax //ECX := (InputCount div 3), (Loop Count)
push edx //Saving (InputCount mod 3)
xor ebx,ebx //Clear EBX
dec esi
test ecx, ecx //InputCount div 3 = 0 ?
jz @next //if InputCount div 3 = 0 then Do Next with (InputCount mod 3) Bytes
mov eax, [esi+1] //EAX := 0x44332211 , Bits = 44444444 33333333 22222222 11111111
bswap eax //EAX := 0x11223344 , Bits = 11111111 22222222 33333333 44444444
shr eax, 8 //EAX := 0x00112233, valid-Bits: 00000000 11111111 22222222 33333333
mov bx, ax //BX := 0x2233, , Bits = 22222222 33333333, valid-Bits: 2222 33333333
mov dx,[ebp + ebx * 2] //DX := CodeTable[Bits:00000000 00000000 00002222 33333333]
mov [edi+2], dx //PWord(@Output[2])^ := DX
shr eax, 12 //First 12-bits, Bits = 00000000 0000000 00001111 11112222
mov bx, ax //BX := Bits:00001111 11112222
mov dx,[ebp + ebx * 2] //DX := CodeTable[Bits:00000000 00000000 00001111 11112222]
mov [edi], dx //PWord(@Output[0])^ := DX
add edi,4 //Inc(Output, 4)
add esi,3 //Inc(Input, 3)
Dec ECX
jz @next //Dec ECX, if ECX = 0 then Goto @next
@loop:
mov eax, [esi] //EAX := 0x66554433 , Bits = 66666666 55555555 44444444 33333333
bswap eax //EAX := 0x33445566 , Bits = 33333333 44444444 55555555 66666666
//valid-Bits: 00000000 44444444 55555555 66666666
mov bx, ax //BX := 0x5566', , Bits = 55555555 66666666, valid-Bits: 5555 66666666
mov dx,[ebp + ebx * 2] //DX := CodeTable[Bits:00000000 00000000 00005555 66666666]
mov [edi+2], dx //PWord(@Output[2])^ := DX
shr eax, 12 //First 12-bits, Bits = 00000000 0000000 00004444 444455555
mov bx, ax //BX := Bits:00004444 44445555
mov dx,[ebp + ebx * 2] //DX := CodeTable[Bits:00000000 00000000 00004444 44445555]
mov [edi], dx //PWord(@Output[0])^ := DX
add edi,4 //Inc(Output, 4)
add esi,3 //Inc(Input, 3)
Dec ECX
jnz @loop //Dec ECX, if ECX <> 0 then Goto @Loop
@next:
inc esi
pop edx //Restore (InputCount mod 3)
test edx, edx // (InputCount mod 3) = 0?
jz @ret //if (InputCount mod 3) = 0 then Exit
//Last one or two Byte(s)
lea ebx, [edx - 4]
neg ebx
sub esi, ebx
mov ax, [esi + 2] //Bits: 11111111 00000000 ( 22222222 11111111 )
xchg ah, al //Bits: 00000000 11111111 ( 11111111 22222222 )
lea ecx, [edx*8]
mov esi, 1
shl esi, cl
dec esi
and eax,esi //Set valid-Bits: 00000000 00000000 00000000 11111111 ( 00000000 00000000 11111111 22222222 )
lea ecx,[edx * 4]
shl eax,cl //last Byte, valid-Bits: 00000000 00000000 00001111 11110000 ( 00000000 00000011 11111122 22222200 )
//last-Byte-valid-Bits: 00110000 ( 00222200 )
mov esi,edx
xor ebx,ebx
@loop2:
//1. valid-Bits: 00001111 11110000 ( 00001122 22222200 )
//2. valid-Bits: N/A ( 00000000 00111111 )
mov bx, ax
mov cx, [ebp + ebx * 2]
mov [edi+edx*2-2], cx
shr eax, 12
dec edx
jnz @loop2
add edi,esi
sub esi,3
neg esi
@loop3:
//Fill-Char(s)
mov Byte ptr [edi+1], 61
inc edi
dec esi
jnz @loop3
@ret:
pop ebp
pop ebx
pop edi
pop esi
@end:
ret
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])));
if I = $e2ca then begin
B64Table[I] := (Word(Byte(Base64_Chars[I and $3f])) shl 8 ) or (Word(Byte(Base64_Chars[(I shr 6) and $3f])));
end;
end;
end.