汇编写的BASE64

  1. unit Base64;
  2. {
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5. Source, Dest: TStream;
  6. begin
  7. if OpenDialog1.Execute then
  8. begin
  9. Source := TFileStream.Create(OpenDialog1.FileName, fmOpenRead); // 打开源文件
  10. Dest := TFileStream.Create('Base64EncodeTest.txt', fmCreate); // Base64编码文件
  11. try
  12. Base64Encode(Source, Dest);
  13. finally
  14. Source.Free;
  15. Dest.Free;
  16. end;
  17.  
  18. Source := TFileStream.Create('Base64EncodeTest.txt', fmOpenRead); // 打开编码文件
  19. Dest := TFileStream.Create('2.exe', fmCreate); // 还原源文件内容
  20. try
  21. Base64Decode(Source, Dest);
  22. Dest.Position := 0;
  23. finally
  24. Source.Free;
  25. Dest.Free;
  26. end;
  27. end;
  28. end;
  29. }
  30.  
  31. interface
  32.  
  33. uses
  34. SysUtils, Classes;
  35.  
  36. type
  37. {$IFDEF UNICODE}
  38. Base64String = AnsiString;
  39. {$ELSE}
  40.  
  41. Base64String = string;
  42. {$ENDIF}
  43.  
  44. // 按源长度SourceSize返回Base64编码所需缓冲区字节数
  45.  
  46. function Base64EncodeBufSize(SourceSize: Integer): Integer;
  47. // 获取Sourec的Base64编码,Base64Buf必须有足够长度。返回实际编码字节数
  48.  
  49. function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer; overload;
  50. // 将Source编码为Base64字符串返回
  51.  
  52. function Base64Encode(const Source; SourceSize: Integer): Base64String; overload;
  53. // 将Source从StartPos开始的Size长度的内容源编码为Base64,写入流Dest。
  54. // Size=0 表示一直编码到文件尾
  55.  
  56. procedure Base64Encode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
  57. // 把字符串Str编码为Base64字符串返回
  58. {$IFDEF UNICODE}
  59.  
  60. function StrToBase64(const Str: AnsiString): Base64String; overload;
  61.  
  62. function StrToBase64(const Str: string): Base64String; overload;
  63. {$ELSE}
  64.  
  65. function StrToBase64(const Str: string): Base64String;
  66. {$ENDIF}
  67.  
  68. // 按给定的编码源Source和长度SourceSize计算并返回解码缓冲区所需字节数
  69.  
  70. function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
  71. // 将Base64编码源Base64Source解码,Buf必须有足够长度。返回实际解码字节数
  72.  
  73. function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer; overload;
  74. // 将Source从StartPos开始的Size长度的Base64编码内容解码,写入流Dest。
  75. // Size=0 表示一直解码到文件尾
  76.  
  77. procedure Base64Decode(Source, Dest: TStream; StartPos: Int64 = 0; Size: Int64 = 0); overload;
  78. // 将Base64编码源Base64Source解码为字符串返回
  79.  
  80. function Base64Decode(const Base64Source; SourceSize: Integer): string; overload;
  81. // 把Base64字符串Base64Str解码为字符串返回
  82.  
  83. function Base64ToStr(const Base64Str: Base64String): string;
  84.  
  85. implementation
  86.  
  87. const
  88. Base64_Chars: array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  89. 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);
  90.  
  91. type
  92. Base64Proc = function(const Source; SourceSize: Integer; var Buf): Integer;
  93.  
  94. procedure Base64Stream(Source, Dest: TStream; Proc: Base64Proc; StartPos, Size: Int64; RBufSize, WBufSize: Integer);
  95. var
  96. RBuf: array of Byte;
  97. WBuf: array of Byte;
  98. RSize, WSize: Integer;
  99. begin
  100. if (StartPos < 0) or (StartPos >= Source.Size) then
  101. Exit;
  102. Source.Position := StartPos;
  103. if (Size <= 0) or (Size > Source.Size - Source.Position) then
  104. Size := Source.Size
  105. else
  106. Size := Size + Source.Position;
  107. SetLength(RBuf, RBufSize);
  108. SetLength(WBuf, WBufSize);
  109. while Size <> Source.Position do
  110. begin
  111. if RBufSize > Size - Source.Position then
  112. RBufSize := Size - Source.Position;
  113. RSize := Source.Read(RBuf[0], RBufSize);
  114. WSize := Proc(RBuf[0], RSize, WBuf[0]);
  115. Dest.Write(WBuf[0], WSize);
  116. end;
  117. end;
  118.  
  119. function Base64EncodeBufSize(SourceSize: Integer): Integer;
  120. begin
  121. Result := ((SourceSize + 2) div 3) shl 2;
  122. end;
  123.  
  124. (****************************************************************************
  125. * *
  126. * BASE64 Encode hint: *
  127. * *
  128. * addr: (high) 4 byte 3 byte 2 byte 1 byte (low) *
  129. * sourec ASCII(3 bytes): 33333333 22222222 11111111 *
  130. * bswap: 11111111 22222222 33333333 00000000 *
  131. * b4 = Base64_Chars[(source >> 8) & 63]: [00333333]->44444444 *
  132. * b3 = Base64_Chars[(source >> 14) & 63]: [00222233]->33333333 *
  133. * b2 = Base64_Chars[(source >> 20) & 63]: [00112222]->22222222 *
  134. * b1 = Base64_Chars[source >> 26]: [00111111]->11111111 *
  135. * b4 << 24 b3 << 16 b2 << 8 b1 *
  136. * dest BASE64(4 bytes) 44444444 33333333 22222222 11111111 *
  137. * *
  138. ****************************************************************************)
  139.  
  140. function Base64Encode(const Source; SourceSize: Integer; var Base64Buf): Integer;
  141. asm
  142. push ebp
  143. push esi
  144. push edi
  145. push ebx
  146. mov esi, eax // esi = Source
  147. mov edi, ecx // edi = Buf
  148. mov eax, edx
  149. cdq
  150. mov ecx, 3
  151. DIV ecx // edx = SourceSize % 3
  152. mov ecx, eax // ecx = SourceSize / 3
  153. test edx, edx
  154. jz @@1
  155. inc eax // eax = (SourceSize + 2) / 3
  156.  
  157. @@1:
  158. push eax
  159. push edx
  160. lea ebp, Base64_Chars
  161. jecxz @Last
  162. cld
  163.  
  164. @EncodeLoop: // while (ecx > 0){
  165. mov edx, [esi] // edx = 00000000 33333333 22222222 11111111
  166. bswap edx // edx = 11111111 22222222 33333333 00000000
  167. push edx
  168. push edx
  169. push edx
  170. pop ebx // ebx = edx
  171. SHR edx, 20
  172. SHR ebx, 26 // ebx = 00111111
  173. AND edx, 63 // edx = 00112222
  174. mov ah, [ebp + edx] // *(word*)edi = (Base64_Chars[edx] << 8) |
  175. mov al, [ebp + ebx] // Base64_Chars[ebx]
  176. stosw // edi += 2
  177. pop edx // edx = 11111111 22222222 33333333 00000000
  178. pop ebx // ebx = edx
  179. SHR edx, 8
  180. SHR ebx, 14
  181. AND edx, 63 // edx = 00333333
  182. AND ebx, 63 // ebx = 00222233
  183. mov ah, [ebp + edx] // *(word*)edi = (Base64_Chars[edx] << 8) |
  184. mov al, [ebp + ebx] // Base64_Chars[ebx]
  185. stosw // edi += 2
  186. add esi, 3 // esi += 3
  187. loop @EncodeLoop // }
  188.  
  189. @Last:
  190. pop ecx // ecx = SourceSize % 3
  191. jecxz @END // if (ecx == 0) return
  192. mov eax, 3d3d0000h // preset 2 bytes '='
  193. mov [edi], eax
  194. test ecx, 2
  195. jnz @@3
  196. mov al, [esi] // if (ecx == 1)
  197. SHL eax, 4 // eax = *esi << 4
  198. jmp @@4
  199.  
  200. @@3:
  201. mov ax, [esi] // else
  202. xchg al, ah // eax = ((*esi << 8) or *(esi + 1)) << 2
  203. SHL eax, 2
  204.  
  205. @@4:
  206. add edi, ecx // edi += ecx
  207. inc ecx // ecx = last encode bytes
  208.  
  209. @LastLoop:
  210. mov edx, eax // for (; cex > 0; ecx --, edi --)
  211. AND edx, 63 // {
  212. mov dl, [ebp + edx] // edx = eax & 63
  213. mov [edi], dl // *edi = Base64_Chars[edx]
  214. SHR eax, 6 // eax >>= 6
  215. dec edi // }
  216. loop @LastLoop
  217.  
  218. @end:
  219. pop eax
  220. SHL eax, 2 // return encode bytes
  221. pop ebx
  222. pop edi
  223. pop esi
  224. pop ebp
  225. end;
  226.  
  227. function Base64Encode(const Source; SourceSize: Integer): Base64String;
  228. begin
  229. SetLength(Result, Base64EncodeBufSize(SourceSize));
  230. Base64Encode(Source, SourceSize, Result[1]);
  231. end;
  232.  
  233. procedure Base64Encode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
  234. begin
  235. Base64Stream(Source, Dest, Base64Encode, StartPos, Size, 6144, 8192);
  236. end;
  237.  
  238. {$IFDEF UNICODE}
  239. function StrToBase64(const Str: AnsiString): Base64String;
  240. begin
  241. Result := Base64Encode(Str[1], Length(Str));
  242. end;
  243.  
  244. function StrToBase64(const Str: string): Base64String;
  245. begin
  246. Result := StrToBase64(AnsiString(Str));
  247. end;
  248. {$ELSE}
  249.  
  250. function StrToBase64(const Str: string): Base64String;
  251. begin
  252. Result := Base64Encode(Str[1], Length(Str));
  253. end;
  254. {$ENDIF}
  255.  
  256. function Base64DecodeBufSize(const Base64Source; SourceSize: Integer): Integer;
  257. asm
  258. mov ecx, eax // ecx = Source + Size
  259. add ecx, edx
  260. mov eax, edx // eax = Size / 4 * 3
  261. SHR edx, 2
  262. SHR eax, 1
  263. add eax, edx
  264. mov edx, eax
  265. jz @@2
  266.  
  267. @@1:
  268. dec ecx
  269. cmp byte ptr[ecx], 61
  270. jne @@2 // if (*--ecx == '=')
  271. dec eax // eax --
  272. jmp @@1
  273.  
  274. @@2: // return eax: BufSize; edx: Size / 4 * 3
  275. end;
  276.  
  277. function Base64Decode(const Base64Source; SourceSize: Integer; var Buf): Integer;
  278. asm
  279. push ebp
  280. push esi
  281. push edi
  282. push ebx
  283. mov esi, eax // esi = Source
  284. mov edi, ecx // edi = Buf
  285. mov ebx, edx
  286. call Base64DecodeBufSize
  287. push eax // eax = Base64DecodeBufSize(Source, SourceSize)
  288. sub edx, eax // edx -= eax // edx: '=' count
  289. lea ebp, Base64_Bytes
  290. SHR ebx, 2 // ebx = SourceSize / 4
  291. test ebx, ebx
  292. jz @END
  293. push edx
  294. cld
  295.  
  296. @DecodeLoop: // for (; ebx > 0; ebx --; edi += 3)
  297. mov ecx, 4 // {
  298. XOR eax, eax
  299.  
  300. @xchgLoop: // for (ecx = 4, eax = 0; ecx > 0; ecx --)
  301. movzx edx, [esi] // {
  302. sub edx, 43 // edx = *(int*)esi - 43
  303. SHL eax, 6 // eax <<= 6
  304. OR al, [ebp + edx]// al |= Base64_Bytes[edx]
  305. inc esi // esi ++
  306. loop @xchgLoop // }
  307. bswap eax // bswap(eax)
  308. dec ebx // if (ebx == 1) break
  309. jz @Last
  310. SHR eax, 8 // eax >>= 8
  311. stosw // *edi = ax; edi += 2
  312. SHR eax, 16 // eax >>= 16
  313. stosb // *edi++ = al
  314. jmp @DecodeLoop // }
  315.  
  316. @Last:
  317. pop ecx
  318. XOR ecx, 3 // ecx = last bytes
  319.  
  320. @LastLoop: // for (; ecx > 0; ecx --)
  321. SHR eax, 8 // {
  322. stosb // eax >>= 8; *edi ++ = al
  323. loop @LastLoop // }
  324.  
  325. @end:
  326. pop eax // return eax
  327. pop ebx
  328. pop edi
  329. pop esi
  330. pop ebp
  331. end;
  332.  
  333. procedure Base64Decode(Source, Dest: TStream; StartPos: Int64; Size: Int64);
  334. begin
  335. Base64Stream(Source, Dest, Base64Decode, StartPos, Size, 8192, 6144);
  336. end;
  337.  
  338. {$IFDEF UNICODE}
  339. function Base64Decode(const Base64Source; SourceSize: Integer): string;
  340. var
  341. s: AnsiString;
  342. begin
  343. SetLength(s, Base64DecodeBufSize(Base64Source, SourceSize));
  344. Base64Decode(Base64Source, SourceSize, s[1]);
  345. Result := string(s);
  346. end;
  347. {$ELSE}
  348.  
  349. function Base64Decode(const Base64Source; SourceSize: Integer): string;
  350. begin
  351. SetLength(Result, Base64DecodeBufSize(Base64Source, SourceSize));
  352. Base64Decode(Base64Source, SourceSize, Result[1]);
  353. end;
  354. {$ENDIF}
  355.  
  356. function Base64ToStr(const Base64Str: Base64String): string;
  357. begin
  358. Result := Base64Decode(Base64Str[1], Length(Base64Str));
  359. end;
  360.  
  361. 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. Flink入门 - CoGroup和Join

    /* *CoGroup */ final StreamExecutionEnvironment streamExecutionEnvironment = StreamExecutionEnvironm ...

  2. linux技能点三 find grep

    find:      1.   按文件名查找    find . -name "a*.txt"     注意双引号:  2.   按文件大小查找 find .-size [+/-] ...

  3. Jenkins使用过程中注意事项

    jenkins自动部署注意事项: 安装jenkins https://blog.csdn.net/qq_37372007/article/details/81586751 1.当提示错误ERROR: ...

  4. C#-NLog记录日志

    Nuget获取包 配置文件 <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns= &quo ...

  5. D. Nested Segments(树状数组、离散化)

    题目链接 参考博客 题意: 给n个线段,对于每个线段问它覆盖了多少个线段. 思路: 由于线段端点是在2e9范围内,所以要先离散化到2e5内(左右端点都离散化了,而且实际上离散化的范围是4e5),然后对 ...

  6. ThinkPHP的路由规则和URL生成,结合django的URL理解

    这个知识点,我觉得蛮重要的. 不作任何路由定义的TP,URL格式和controller之间,相当于强绑定. 路由配置,让URL和controller的关系可以自定义. URL生成,让controlle ...

  7. 用Python添加写入数据到已经存在的Excel的xlsx文件

    # coding:utf-8 from openpyxl import load_workbook import openpyxl # 写入已存在的xlsx文件第一种方法 # class Write_ ...

  8. datagrid中的排序

    sortable的属性设置为true后就能看到标志 属性名称 属性值类型 描述 默认值 sortable boolean 如果为true,则允许列使用排序. undefined order strin ...

  9. Python开发应用-正则表达进行排序搜索

    re模块提供了3个方法对输入的字符串进行确切的查询,match和search最多只会返回一个匹配条件的子串,可以理解为非贪婪模式,而findall会返回N个匹配条件的子串,可以理解为贪婪模式 re.m ...

  10. js里调用函数时,函数名带括号与不带括号的区别

    function test(){ return 1;}var a=test;console.log(a);//输出[Function: test]var b=test();console.log(b) ...