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