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

    ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提供分析依据. ETL是BI项目重要的一个环节. 通常情况下,在 ...

  2. 使用ZeroClipboard 复制指定内容到剪切板

    有些时候,我们希望让用户在网页上完成某个操作就能自动将指定的内容复制到用户计算机的剪贴板中.但是出于安全原因,大多数现代浏览器都未提供通用的剪贴板复制接口(或即便有,也默认被禁用).只有IE浏览器可以 ...

  3. 线性回归-API

    线性回归的定义 利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式 线性回归的分类 线性关系 非线性关系 损失函数 最小二乘法 线性回归优化方法 正规方程 ...

  4. MyBatis日记(四):MyBatis——insert、update、delete、select

    MyBatis简单增删改查操作,此处所做操作,皆是在之前创建的MyBatis的Hello world的工程基础上所做操作. 首先在接口文件(personMapper.java)中,添加操作方法: pa ...

  5. WSL quick overview

    简介 WSL,是Windows Subsystem for Linux的缩写,字面意义上理解就是WIndows下的Linux子系统.WSL 由Microsoft Windows内核团队创建,目前如果最 ...

  6. Python入门篇-数据结构堆排序Heap Sort

    Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...

  7. Linux服务-rsync

    目录 1. rsync简介 2. rsync特性 3. rsync的ssh认证协议 4. rsync命令 5. rsync+inotify Linux服务-rsync 1. rsync简介 rsync ...

  8. InnoDB存储引擎与MyIsam存储引擎的区别

    特性比较 mysql5.5之后默认的存储引擎为InnoDB,在此之前默认存储引擎是MyIsam 特点 MyIsam InnoDB 锁机制 表锁 行锁 事务 不支持 支持 外键 不支持 支持 B树索引 ...

  9. charAt,charCode,fromCharCode区别

    1.charAt 返回字符串指定位置的字符 2.charCode 返回字符串指定位置字符Unicode编码 3.fromCharCode 用Unicode编码创建字符串 我们来看下例子 var str ...

  10. 解决PHP处理图片时内存占用过高问题

    用过GD库的同学可能都知道,使用imagecreatetruecolor()函数创建一个真彩色的画布是第一步.但是,如果画布的宽高超过平常的宽高,会带来极大的内存消耗.比如,一个9600×4800的画 ...