汇编写的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.

  

汇编写的BASE64的更多相关文章

  1. 使用jframe编写一个base64加密解密工具

    该工具可以使用exe4j来打包成exe工具(如何打包自己百度) 先上截图功能 运行main方法后,会弹出如下窗口 输入密文 然后点击解密,在点格式化 代码分享 package tools;import ...

  2. 汇编写hello world

    .global main main: mov ip, sp stmfd sp!, {fp, ip, lr} sub fp, ip, # ldr r0, =he mov lr, pc b printf ...

  3. 汇编写下strcpy

    #include <stdio.h> int main() { char *source = "hello world\n"; ] = {}; char *p = de ...

  4. [自制简单操作系统] 1、从0-1到汇编再到c语言的奥秘

    目录: 1.用0-1编写最简单的操作系统 2.用汇编改写上面0-1程序 2.1 只用DB的汇编改写版  2.2 加入RESB汇编的改写版  2.3 进一步使用汇编替换0-1文件  2.4 核心程序也用 ...

  5. 前端开发:如何写一手漂亮的 Vue

    前几日听到一句生猛与激励并存,可怕与尴尬同在,最无奈也无解的话:"90后,你的中年危机已经杀到".这令我很受触动.显然,这有些夸张了,但就目前这日复一日的庸碌下去,眨眼的功夫,那情 ...

  6. runtime理论知识

    http://southpeak.github.io/2014/10/25/objective-c-runtime-1/ 转载http://www.jianshu.com/p/6b905584f536 ...

  7. 李洪强经典面试题152-Runtime

    李洪强经典面试题152-Runtime   Runtime Runtime是什么 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码, ...

  8. iOS---runtime介绍

    本文目录 1.Runtime简介 2.Runtime相关的头文件 3.技术点和应用场景 3_1.获取属性\成员变量列表 3_2.交换方法实现 3_3.类\对象的关联对象,假属性 3_4.动态添加方法, ...

  9. iOS开发——高级特性&Runtime运行时特性详解

    Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 ...

随机推荐

  1. Workerman简单开发示例实践(一)

    一.去官网下载workerman,地址:https://www.workerman.net/download,下载后解压任意文件夹. 二.在解压文件目录下新建http_test.php,输入如下代码: ...

  2. Java 之 Maven 基础

    一.Maven 介绍 1.什么是 Maven Maven 是一个项目管理工具,它包含了一个项目对象模型(POM:Project Object Model),一组标准集合,一个项目生命周期(Projec ...

  3. Linux负载模拟

    转载:https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79063392 CPU 下面命令会创建 CPU 负荷,方法是通过压缩随机数据并将结果发送 ...

  4. Hive架构分析

    一.Hive三种设计模式 1.默认配置[使用Netty存储元数据] 2.mysql[使用mysql存储元数据] 3.配置Thrift[使用mysql存储元数据] 二.执行步骤 三.scala访问Hiv ...

  5. Oracle 数据类型比较规则

    数值 较大的值被认为大于较小的值.所有负数都小于零,所有正数都小于零.因此,-1小于100:-100小于-1. 浮点值NaN(not a number))大于任何其他数值,且等于自身. 日期时间值 较 ...

  6. cadvisor应用

    cadvisor主页:https://github.com/google/cadvisor 容器主页:https://hub.docker.com/r/google/cadvisor cAdvisor ...

  7. OSPF但区域配置

    原理概述 实验内容 实验拓扑 实验编址 实验步骤1.基本配置配置完成后,使用ping命令检测 2.部署单区域OSPF网络使用命令ospf创建并运行OSPF 其中1是进程号,如果没有写明进程号,则默认为 ...

  8. 使用Cloudera Manager添加Sentry服务

    使用Cloudera Manager添加Sentry服务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.通过CM添加Sentry服务 1>.点击添加服务进入CM服务安装向 ...

  9. i++和++i的真正区别

    原文:https://blog.csdn.net/c15158032319/article/details/78209740 记得刚开始学编程的时候还是从c语言开始的,还是看的谭浩强写的那本书,上面对 ...

  10. O(n) 取得数组中每个元素右边最后一个比它大的元素

    题目 2019.9.7,icpc徐州网络赛的E题 XKC's basketball team ,计蒜客上还可以做. 链接:https://nanti.jisuanke.com/t/41387 Inpu ...