汇编写的BASE64

unit Base64;
{
procedure TForm1.Button1Click(Sender: TObject);
var
Source, Dest: TStream;
begin
if OpenDialog1.Execute then
begin
Source := TFileStream.Create(OpenDialog1.FileName, fmOpenRead); // 打开源文件
Dest := TFileStream.Create('Base64EncodeTest.txt', fmCreate); // Base64编码文件
try
Base64Encode(Source, Dest);
finally
Source.Free;
Dest.Free;
end; Source := TFileStream.Create('Base64EncodeTest.txt', fmOpenRead); // 打开编码文件
Dest := TFileStream.Create('2.exe', fmCreate); // 还原源文件内容
try
Base64Decode(Source, Dest);
Dest.Position := 0;
finally
Source.Free;
Dest.Free;
end;
end;
end;
} interface uses
SysUtils, Classes; type
{$IFDEF UNICODE}
Base64String = AnsiString;
{$ELSE} Base64String = string;
{$ENDIF} // 按源长度SourceSize返回Base64编码所需缓冲区字节数 function Base64EncodeBufSize(SourceSize: Integer): Integer;
// 获取Sourec的Base64编码,Base64Buf必须有足够长度。返回实际编码字节数 function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer; overload;
// 将Source编码为Base64字符串返回 function Base64Encode(const Source; SourceSize: Integer): Base64String; overload;
// 将Source从StartPos开始的Size长度的内容源编码为Base64,写入流Dest。
// Size=0 表示一直编码到文件尾 procedure Base64Encode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
// 把字符串Str编码为Base64字符串返回
{$IFDEF UNICODE} function StrToBase64(const Str: AnsiString): Base64String; overload; function StrToBase64(const Str: string): Base64String; overload;
{$ELSE} function StrToBase64(const Str: string): Base64String;
{$ENDIF} // 按给定的编码源Source和长度SourceSize计算并返回解码缓冲区所需字节数 function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
// 将Base64编码源Base64Source解码,Buf必须有足够长度。返回实际解码字节数 function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer; overload;
// 将Source从StartPos开始的Size长度的Base64编码内容解码,写入流Dest。
// Size=0 表示一直解码到文件尾 procedure Base64Decode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
// 将Base64编码源Base64Source解码为字符串返回 function Base64Decode(const Base64Source; SourceSize: Integer): string; overload;
// 把Base64字符串Base64Str解码为字符串返回 function Base64ToStr(const Base64Str: Base64String): string; implementation const
Base64_Chars: array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
Base64_Bytes: array[0..79] of Byte = (62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51); type
Base64Proc = function(const Source; SourceSize: Integer; var Buf): Integer; procedure Base64Stream(Source, Dest: TStream; Proc: Base64Proc; StartPos, Size: Int64; RBufSize, WBufSize: Integer);
var
RBuf: array of Byte;
WBuf: array of Byte;
RSize, WSize: Integer;
begin
if (StartPos < 0) or (StartPos >= Source.Size) then
Exit;
Source.Position := StartPos;
if (Size <= 0) or (Size > Source.Size - Source.Position) then
Size := Source.Size
else
Size := Size + Source.Position;
SetLength(RBuf, RBufSize);
SetLength(WBuf, WBufSize);
while Size <> Source.Position do
begin
if RBufSize > Size - Source.Position then
RBufSize := Size - Source.Position;
RSize := Source.Read(RBuf[0], RBufSize);
WSize := Proc(RBuf[0], RSize, WBuf[0]);
Dest.Write(WBuf[0], WSize);
end;
end; function Base64EncodeBufSize(SourceSize: Integer): Integer;
begin
Result := ((SourceSize + 2) div 3) shl 2;
end; (****************************************************************************
* *
* BASE64 Encode hint: *
* *
* addr: (high) 4 byte 3 byte 2 byte 1 byte (low) *
* sourec ASCII(3 bytes): 33333333 22222222 11111111 *
* bswap: 11111111 22222222 33333333 00000000 *
* b4 = Base64_Chars[(source >> 8) & 63]: [00333333]->44444444 *
* b3 = Base64_Chars[(source >> 14) & 63]: [00222233]->33333333 *
* b2 = Base64_Chars[(source >> 20) & 63]: [00112222]->22222222 *
* b1 = Base64_Chars[source >> 26]: [00111111]->11111111 *
* b4 << 24 b3 << 16 b2 << 8 b1 *
* dest BASE64(4 bytes) 44444444 33333333 22222222 11111111 *
* *
****************************************************************************) function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer;
asm
push ebp
push esi
push edi
push ebx
mov esi, eax // esi = Source
mov edi, ecx // edi = Buf
mov eax, edx
cdq
mov ecx, 3
DIV ecx // edx = SourceSize % 3
mov ecx, eax // ecx = SourceSize / 3
test edx, edx
jz @@1
inc eax // eax = (SourceSize + 2) / 3 @@1:
push eax
push edx
lea ebp, Base64_Chars
jecxz @Last
cld @EncodeLoop: // while (ecx > 0){
mov edx, [esi] // edx = 00000000 33333333 22222222 11111111
bswap edx // edx = 11111111 22222222 33333333 00000000
push edx
push edx
push edx
pop ebx // ebx = edx
SHR edx, 20
SHR ebx, 26 // ebx = 00111111
AND edx, 63 // edx = 00112222
mov ah, [ebp + edx] // *(word*)edi = (Base64_Chars[edx] << 8) |
mov al, [ebp + ebx] // Base64_Chars[ebx]
stosw // edi += 2
pop edx // edx = 11111111 22222222 33333333 00000000
pop ebx // ebx = edx
SHR edx, 8
SHR ebx, 14
AND edx, 63 // edx = 00333333
AND ebx, 63 // ebx = 00222233
mov ah, [ebp + edx] // *(word*)edi = (Base64_Chars[edx] << 8) |
mov al, [ebp + ebx] // Base64_Chars[ebx]
stosw // edi += 2
add esi, 3 // esi += 3
loop @EncodeLoop // } @Last:
pop ecx // ecx = SourceSize % 3
jecxz @END // if (ecx == 0) return
mov eax, 3d3d0000h // preset 2 bytes '='
mov [edi], eax
test ecx, 2
jnz @@3
mov al, [esi] // if (ecx == 1)
SHL eax, 4 // eax = *esi << 4
jmp @@4 @@3:
mov ax, [esi] // else
xchg al, ah // eax = ((*esi << 8) or *(esi + 1)) << 2
SHL eax, 2 @@4:
add edi, ecx // edi += ecx
inc ecx // ecx = last encode bytes @LastLoop:
mov edx, eax // for (; cex > 0; ecx --, edi --)
AND edx, 63 // {
mov dl, [ebp + edx] // edx = eax & 63
mov [edi], dl // *edi = Base64_Chars[edx]
SHR eax, 6 // eax >>= 6
dec edi // }
loop @LastLoop @end:
pop eax
SHL eax, 2 // return encode bytes
pop ebx
pop edi
pop esi
pop ebp
end; function Base64Encode(const Source; SourceSize: Integer): Base64String;
begin
SetLength(Result, Base64EncodeBufSize(SourceSize));
Base64Encode(Source, SourceSize, Result[1]);
end; procedure Base64Encode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
begin
Base64Stream(Source, Dest, Base64Encode, StartPos, Size, 6144, 8192);
end; {$IFDEF UNICODE}
function StrToBase64(const Str: AnsiString): Base64String;
begin
Result := Base64Encode(Str[1], Length(Str));
end; function StrToBase64(const Str: string): Base64String;
begin
Result := StrToBase64(AnsiString(Str));
end;
{$ELSE} function StrToBase64(const Str: string): Base64String;
begin
Result := Base64Encode(Str[1], Length(Str));
end;
{$ENDIF} function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
asm
mov ecx, eax // ecx = Source + Size
add ecx, edx
mov eax, edx // eax = Size / 4 * 3
SHR edx, 2
SHR eax, 1
add eax, edx
mov edx, eax
jz @@2 @@1:
dec ecx
cmp byte ptr[ecx], 61
jne @@2 // if (*--ecx == '=')
dec eax // eax --
jmp @@1 @@2: // return eax: BufSize; edx: Size / 4 * 3
end; function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer;
asm
push ebp
push esi
push edi
push ebx
mov esi, eax // esi = Source
mov edi, ecx // edi = Buf
mov ebx, edx
call Base64DecodeBufSize
push eax // eax = Base64DecodeBufSize(Source, SourceSize)
sub edx, eax // edx -= eax // edx: '=' count
lea ebp, Base64_Bytes
SHR ebx, 2 // ebx = SourceSize / 4
test ebx, ebx
jz @END
push edx
cld @DecodeLoop: // for (; ebx > 0; ebx --; edi += 3)
mov ecx, 4 // {
XOR eax, eax @xchgLoop: // for (ecx = 4, eax = 0; ecx > 0; ecx --)
movzx edx, [esi] // {
sub edx, 43 // edx = *(int*)esi - 43
SHL eax, 6 // eax <<= 6
OR al, [ebp + edx]// al |= Base64_Bytes[edx]
inc esi // esi ++
loop @xchgLoop // }
bswap eax // bswap(eax)
dec ebx // if (ebx == 1) break
jz @Last
SHR eax, 8 // eax >>= 8
stosw // *edi = ax; edi += 2
SHR eax, 16 // eax >>= 16
stosb // *edi++ = al
jmp @DecodeLoop // } @Last:
pop ecx
XOR ecx, 3 // ecx = last bytes @LastLoop: // for (; ecx > 0; ecx --)
SHR eax, 8 // {
stosb // eax >>= 8; *edi ++ = al
loop @LastLoop // } @end:
pop eax // return eax
pop ebx
pop edi
pop esi
pop ebp
end; procedure Base64Decode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
begin
Base64Stream(Source, Dest, Base64Decode, StartPos, Size, 8192, 6144);
end; {$IFDEF UNICODE}
function Base64Decode(const Base64Source; SourceSize: Integer): string;
var
s: AnsiString;
begin
SetLength(s, Base64DecodeBufSize(Base64Source, SourceSize));
Base64Decode(Base64Source, SourceSize, s[1]);
Result := string(s);
end;
{$ELSE} function Base64Decode(const Base64Source; SourceSize: Integer): string;
begin
SetLength(Result, Base64DecodeBufSize(Base64Source, SourceSize));
Base64Decode(Base64Source, SourceSize, Result[1]);
end;
{$ENDIF} function Base64ToStr(const Base64Str: Base64String): string;
begin
Result := Base64Decode(Base64Str[1], Length(Base64Str));
end; end.

  

最新文章

  1. Leetcode-463 Island Perimeter
  2. gcc编译时头文件和库文件搜索路径
  3. Android开发工具类
  4. Hybrid框架UI重构之路:四、分而治之
  5. input按钮上传按钮样式
  6. 使用ajax上传中遇到的问题
  7. 【HDOJ】1241 Oil Deposits
  8. CSV 客座文章系列:KGroup 通过 Windows Azure 将 Qoob 内容管理发布到云中
  9. Ling to entity实现分页
  10. PHP方法实现1-9数列中添加‘+’,‘-’或&#39;&#39;,使和为100,并输出数列
  11. A potentially dangerous Request.Form value was detected from the client问题处理
  12. 《java入门第一季》正则表达式小案例
  13. Azure CosmosDB (3) 选择适当的一致性级别
  14. 微信小程序上传图片,视频及预览
  15. bootStrap中的翻页效果
  16. 修改class文件
  17. The Alphabet Sticker
  18. docker下 klee第一个测试
  19. android 网络
  20. Battery Historian之App耗电量测试

热门文章

  1. java Document生成和解析xml
  2. 子网掩码与ip地址的关系
  3. python系列:一、Urllib库的基本使用
  4. selenium 定位元素方法
  5. Java开发环境之RabbitMQ
  6. Python——生成器&amp;推导式
  7. JAVA-JNI调用使用
  8. HTML&amp;CSS基础-meta标签
  9. Codeforces A. Game on Tree(期望dfs)
  10. ThinkPHP的路由规则和URL生成,结合django的URL理解