- function GetSizeCoder3To4(InputCount: Integer): Integer; inline;
- begin
- Result := (InputCount+2) div 3 * 4
- end;
- procedure Base64Encode(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, @codetable //load B64-CodeTable-8bit
- 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
- push edx
- 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
- mov bl, ch //BL := 0x33 , Bits = 33333333, valid-Bits: 00333333
- mov dh,[ebp + ebx] //DH := CodeTable[Bits: **333333]
- shr ecx, 14 //Prior 6-bits, Bits = 00000000 00000011 11111122 22222233
- mov bl, cl //BL := Bits:22222233, valid-Bits: 00222233
- mov dl,[ebp + ebx] //DL := CodeTable[Bits: **222233]
- mov [edi+2], dx //Output[2] := DX
- shr ecx, 6 //Prior 6-bits, Bits = 0000000 00000000 00001111 11112222
- mov bl, cl //BL := Bits:11112222, valid-Bits: 00112222
- mov dh, [ebp + ebx] //DH := CodeTable[Bits: **112222]
- shr ecx, 6 //First 6-bits, Bits = 00000000 00000000 00000000 00111111
- mov bl, cl //BL := Bits:00111111
- mov dl,[ebp + ebx] //DL := CodeTable[Bits: **111111]
- mov [edi], dx //Output[0] := DX
- add edi,4 //Inc(Output, 4)
- add esi,3 //Inc(Input, 3)
- Dec EAX //Dec EAX
- jz @next //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
- mov bl, cl //BL := 0x66 , Bits = 66666666, valid-Bits: 00666666
- mov dh, [ebp + ebx] //DH := CodeTable[Bits: **666666]
- shr ecx, 6 //Prior 6-bits, Bits = 00000033 33333344 44444455 55555566
- mov bl, cl //BL := Bits:55555566, valid-Bits: 00555566
- mov dl,[ebp + ebx] //DL := CodeTable[Bits: **555566]
- mov [edi+2], dx //Output[2] := DX
- shr ecx, 6 //Prior 6-bits, Bits = 0000000 00003333 33334444 44445555
- mov bl, cl //BL := Bits:44445555, valid-Bits: 00445555
- mov dh,[ebp + ebx] //DH := CodeTable[Bits: **445555]
- shr ecx, 6 //First 6-bits, Bits = 00000000 00000000 00333333 33444444
- mov bl, cl //BL := Bits:33444444, valid-Bits: 00444444
- mov dl,[ebp + ebx] //DL := CodeTable[Bits: **444444]
- mov [edi], dx //Output[0] := DX
- add edi,4 //Inc(Output, 4)
- add esi,3 //Inc(Input, 3)
- Dec EAX
- jnz @loop //Dec ECX, if ECX <> 0 then Goto @Loop
- @next:
- pop edx
- 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
- //Last two-Bytes
- @TwoBytes:
- mov ax, [esi + 1] //Bits: 22222222 11111111
- xchg al, ah //Bits: 11111111 22222222
- lea eax, [eax * 4] //shl ecx, 2 ,Bits: 00000000 00000011 11111122 22222200
- mov bl, al //Bits: 22222200, valid-Bits: 00222200
- mov dh, [ebp + ebx] //DH := CodeTable[Bits: **222200]
- shr eax, 6 //Bits: 00000000 00000000 00001111 11112222
- mov bl, al //Bits: 11112222, valid-Bits: 00112222
- mov dl, [ebp + ebx] //DL := CodeTable[Bits: **112222]
- mov [edi + 1], dx
- shr eax, 6 //Bits: 00000000 00000000 00000000 00111111
- mov dl, [ebp + eax] //DL := CodeTable[Bits: 00111111]
- mov [edi], dl
- mov Byte ptr [edi + 3], 61 //'='
- pop ebp
- pop ebx
- pop edi
- pop esi
- ret
- //Last one-Byte
- @OneByte:
- mov al, [esi + 1] // Bits: 11111111
- lea ebx, [eax * 8] // EBX := EAX SHL 3, Bits: 00000000 00000000 00000111 11111000
- and ebx, $18 // Bits: 00000000 00000000 00000000 00011000
- mov dh, [ebp + ebx * 2] // Bits: 00000000 00000000 00000000 00110000
- // DH := CodeTable[Bits: **110000]
- shr eax, 2 // Bits: 00000000 00000000 00000000 00111111
- mov dl, [ebp + eax] // DL := CodeTable[Bits: **111111]
- mov [edi], dx
- mov Byte ptr [edi + 2], 61 //'='
- mov Byte ptr [edi + 3], 61 //'='
- pop ebp
- pop ebx
- pop edi
- pop esi
- @ret:
- ret
- @CodeTable:
- //Bits: 00******
- db 65, 66, 67, 68, 69, 70, 71, 72
- db 73, 74, 75, 76, 77, 78, 79, 80
- db 81, 82, 83, 84, 85, 86, 87, 88
- db 89, 90, 97, 98, 99,100,101,102
- db 103,104,105,106,107,108,109,110
- db 111,112,113,114,115,116,117,118
- db 119,120,121,122, 48, 49, 50, 51
- db 52, 53, 54, 55, 56, 57, 43, 47
- //Bits: 01******
- db 65, 66, 67, 68, 69, 70, 71, 72
- db 73, 74, 75, 76, 77, 78, 79, 80
- db 81, 82, 83, 84, 85, 86, 87, 88
- db 89, 90, 97, 98, 99,100,101,102
- db 103,104,105,106,107,108,109,110
- db 111,112,113,114,115,116,117,118
- db 119,120,121,122, 48, 49, 50, 51
- db 52, 53, 54, 55, 56, 57, 43, 47
- //Bits: 10******
- db 65, 66, 67, 68, 69, 70, 71, 72
- db 73, 74, 75, 76, 77, 78, 79, 80
- db 81, 82, 83, 84, 85, 86, 87, 88
- db 89, 90, 97, 98, 99,100,101,102
- db 103,104,105,106,107,108,109,110
- db 111,112,113,114,115,116,117,118
- db 119,120,121,122, 48, 49, 50, 51
- db 52, 53, 54, 55, 56, 57, 43, 47
- //Bits: 11******
- db 65, 66, 67, 68, 69, 70, 71, 72
- db 73, 74, 75, 76, 77, 78, 79, 80
- db 81, 82, 83, 84, 85, 86, 86, 88
- db 89, 90, 97, 98, 99,100,101,102
- db 103,104,105,106,107,108,109,110
- db 111,112,113,114,115,116,117,118
- db 119,120,121,122, 48, 49, 50, 51
- db 52, 53, 54, 55, 56, 57, 43, 47
- end;
- //测试代码
- procedure TForm1.Button1Click(Sender: TObject);
- var
- StrSrc, StrDst: AnsiString;
- begin
- StrSrc := '测试一下Base64编码,看看结果是什么...';
- SetLength(StrDst, GetSizeCoder3To4(Length(StrSrc)));
- Base64Encode(Length(StrSrc), Pointer(StrSrc), Pointer(StrDst));
- MessageBox(GetActiveWindow,PAnsiChar(StrDst),'Base64编码输出',MB_OK or MB_ICONINFORMATION);
- end;