您现在的位置:首页 >> 基础算法 >> window基础 >> 内容

Delphi嵌入式汇编版高性能Base64编码算法

时间:2011/9/3 15:28:05 点击:

  核心提示:由于目前编写的代码最终都是在服务器上运行的,所以有时候也会有点变态地追求所谓的性能问题,因此希望各位能够贡献点资源上来,先谢过。先发一个比较变态的单元,其实也不是什么好东西,只是一个采用了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.

作者:unsigned 来源:转载
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • 盒子文章(www.2ccc.com) © 2020 版权所有 All Rights Reserved.
  • 沪ICP备05001939号