uEncrypt.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:11k
源码类别:

Email服务器

开发平台:

Delphi

  1. unit uEncrypt;
  2. interface
  3. uses Classes,SysUtils,Forms,Dialogs,Windows;
  4. type 
  5.   ICipher=interface
  6.     function DecodeString(const S:String):string;
  7.     function EncodeString(const S:String):string;
  8.     
  9.     procedure  DecodeStream( Stream:TMemoryStream);
  10.     procedure EncodeStream( Stream:TMemoryStream);
  11.   end;
  12.   TBaseCipher=class(TInterfacedObject,ICipher)
  13.   public
  14.     procedure  DecodeStream( Stream:TMemoryStream);
  15.     procedure EncodeStream( Stream:TMemoryStream);
  16.     function DecodeString(const S:String):string;virtual;abstract;
  17.     function EncodeString(const S:String):string;virtual;abstract;
  18.   end;
  19.   TMIMECipher=class(TBaseCipher)   //Base64加密解密
  20.   protected
  21.     function  MimeDecodePartial (const InputBuffer; const InputBytesCount: Cardinal;
  22.         out OutputBuffer; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
  23.     function MimeDecodePartialEnd (out OutputBuffer; const ByteBuffer: Cardinal;
  24.       const ByteBufferSpace: Cardinal): Cardinal;
  25.     procedure MimeEncodeNoCRLF (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  26.     function MimeEncodedSize (const i: Cardinal): Cardinal;
  27.     procedure MimeEncodeFullLines (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  28.     procedure MimeEncode (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  29.   public
  30.     function DecodeString (const s: String): String; override;
  31.     function EncodeString (const s: String): String; override;
  32.   end;
  33. implementation
  34. const
  35.   MIME_ENCODED_LINE_BREAK = 76;
  36.   MIME_DECODED_LINE_BREAK = MIME_ENCODED_LINE_BREAK div 4 * 3;
  37.   BUFFER_SIZE        = MIME_DECODED_LINE_BREAK * 3 * 4 * 16;
  38.   MIME_ENCODE_TABLE  : array[0..63] of Byte = (
  39.     065, 066, 067, 068, 069, 070, 071, 072, // 00 - 07
  40.     073, 074, 075, 076, 077, 078, 079, 080, // 08 - 15
  41.     081, 082, 083, 084, 085, 086, 087, 088, // 16 - 23
  42.     089, 090, 097, 098, 099, 100, 101, 102, // 24 - 31
  43.     103, 104, 105, 106, 107, 108, 109, 110, // 32 - 39
  44.     111, 112, 113, 114, 115, 116, 117, 118, // 40 - 47
  45.     119, 120, 121, 122, 048, 049, 050, 051, // 48 - 55
  46.     052, 053, 054, 055, 056, 057, 043, 047); // 56 - 63
  47.   MIME_PAD_CHAR      = Byte ('=');
  48.   MIME_DECODE_TABLE  : array[Byte] of Cardinal = (
  49.   255, 255, 255, 255, 255, 255, 255, 255, //  00 -  07
  50.   255, 255, 255, 255, 255, 255, 255, 255, //  08 -  15
  51.   255, 255, 255, 255, 255, 255, 255, 255, //  16 -  23
  52.   255, 255, 255, 255, 255, 255, 255, 255, //  24 -  31
  53.   255, 255, 255, 255, 255, 255, 255, 255, //  32 -  39
  54.   255, 255, 255, 062, 255, 255, 255, 063, //  40 -  47
  55.   052, 053, 054, 055, 056, 057, 058, 059, //  48 -  55
  56.   060, 061, 255, 255, 255, 255, 255, 255, //  56 -  63
  57.   255, 000, 001, 002, 003, 004, 005, 006, //  64 -  71
  58.   007, 008, 009, 010, 011, 012, 013, 014, //  72 -  79
  59.   015, 016, 017, 018, 019, 020, 021, 022, //  80 -  87
  60.   023, 024, 025, 255, 255, 255, 255, 255, //  88 -  95
  61.   255, 026, 027, 028, 029, 030, 031, 032, //  96 - 103
  62.   033, 034, 035, 036, 037, 038, 039, 040, // 104 - 111
  63.   041, 042, 043, 044, 045, 046, 047, 048, // 112 - 119
  64.   049, 050, 051, 255, 255, 255, 255, 255, // 120 - 127
  65.   255, 255, 255, 255, 255, 255, 255, 255,
  66.   255, 255, 255, 255, 255, 255, 255, 255,
  67.   255, 255, 255, 255, 255, 255, 255, 255,
  68.   255, 255, 255, 255, 255, 255, 255, 255,
  69.   255, 255, 255, 255, 255, 255, 255, 255,
  70.   255, 255, 255, 255, 255, 255, 255, 255,
  71.   255, 255, 255, 255, 255, 255, 255, 255,
  72.   255, 255, 255, 255, 255, 255, 255, 255,
  73.   255, 255, 255, 255, 255, 255, 255, 255,
  74.   255, 255, 255, 255, 255, 255, 255, 255,
  75.   255, 255, 255, 255, 255, 255, 255, 255,
  76.   255, 255, 255, 255, 255, 255, 255, 255,
  77.   255, 255, 255, 255, 255, 255, 255, 255,
  78.   255, 255, 255, 255, 255, 255, 255, 255,
  79.   255, 255, 255, 255, 255, 255, 255, 255,
  80.   255, 255, 255, 255, 255, 255, 255, 255);
  81.   
  82. type
  83.  PByte4 = ^TByte4;
  84.  TByte4 = packed record
  85.   b1: Byte;
  86.   b2: Byte;
  87.   b3: Byte;
  88.   b4: Byte;
  89.  end;
  90.  PByte3 = ^TByte3;
  91.  TByte3 = packed record
  92.   b1: Byte;
  93.   b2: Byte;
  94.   b3: Byte;
  95.  end;
  96. //==============================================================================
  97.   { TBaseCipher }
  98. procedure TBaseCipher.DecodeStream(Stream: TMemoryStream);
  99. var
  100.   p:PChar;
  101.   S,Dest:string;
  102. begin
  103.   GetMem(P,Stream.Size);
  104.   try
  105.     ZeroMemory(P,Stream.Size);
  106.     CopyMemory(P,Stream.Memory,Stream.Size);
  107.     S:=StrPas(p);
  108.     Dest:=DecodeString(S);
  109.     Stream.Clear;
  110.     Stream.Position:=0;
  111.     Stream.WriteBuffer(Dest[1],Length(Dest));
  112.   finally
  113.     FreeMem(P);
  114.   end;
  115. end;
  116. procedure TBaseCipher.EncodeStream( Stream: TMemoryStream);
  117. var
  118.   p:PChar;
  119.   S,Dest:string;
  120. begin
  121.   GetMem(P,Stream.Size);
  122.   try
  123.     ZeroMemory(P,Stream.Size);
  124.     CopyMemory(P,Stream.Memory,Stream.Size);
  125.     S:=StrPas(p);
  126.     Dest:=EncodeString(S);
  127.     Stream.Clear;
  128.     Stream.Position:=0;
  129.     Stream.WriteBuffer(Dest[1],Length(Dest));
  130.   finally
  131.     FreeMem(P);
  132.   end;
  133. end;
  134. { TMIMECipher }
  135. function TMIMECipher.MimeDecodePartial (const InputBuffer; const InputBytesCount: Cardinal;
  136. out OutputBuffer; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
  137. var
  138.  lByteBuffer, lByteBufferSpace, c: Cardinal;
  139.  InPtr, OuterLimit  : ^Byte;
  140.  OutPtr             : PByte3;
  141. begin
  142.  if InputBytesCount > 0 then
  143.   begin
  144.    InPtr := @InputBuffer;
  145.    Cardinal (OuterLimit) := Cardinal (InPtr) + InputBytesCount;
  146.    OutPtr := @OutputBuffer;
  147.    lByteBuffer := ByteBuffer;
  148.    lByteBufferSpace := ByteBufferSpace;
  149.    while InPtr <> OuterLimit do
  150.     begin
  151.      c := MIME_DECODE_TABLE[InPtr^];
  152.      Inc (InPtr);
  153.      if c = $FF then Continue;
  154.      lByteBuffer := lByteBuffer shl 6;
  155.      lByteBuffer := lByteBuffer or c;
  156.      Dec (lByteBufferSpace);
  157.      if lByteBufferSpace <> 0 then Continue;
  158.      OutPtr^.b3 := Byte (lByteBuffer);
  159.      lByteBuffer := lByteBuffer shr 8;
  160.      OutPtr^.b2 := Byte (lByteBuffer);
  161.      lByteBuffer := lByteBuffer shr 8;
  162.      OutPtr^.b1 := Byte (lByteBuffer);
  163.      lByteBuffer := 0;
  164.      Inc (OutPtr);
  165.      lByteBufferSpace := 4;
  166.     end;
  167.    ByteBuffer := lByteBuffer;
  168.    ByteBufferSpace := lByteBufferSpace;
  169.    Result := Cardinal (OutPtr) - Cardinal (@OutputBuffer);
  170.   end
  171.  else
  172.   Result := 0;
  173. end;
  174. function TMIMECipher.MimeDecodePartialEnd (out OutputBuffer; const ByteBuffer: Cardinal;
  175.   const ByteBufferSpace: Cardinal): Cardinal;
  176. var
  177.  lByteBuffer : Cardinal;
  178. begin
  179.  case ByteBufferSpace of
  180.   1:
  181.    begin
  182.     lByteBuffer := ByteBuffer shr 2;
  183.     PByte3 (@OutputBuffer)^.b2 := Byte (lByteBuffer);
  184.     lByteBuffer := lByteBuffer shr 8;
  185.     PByte3 (@OutputBuffer)^.b1 := Byte (lByteBuffer);
  186.     Result := 2;
  187.    end;
  188.   2:
  189.    begin
  190.     lByteBuffer := ByteBuffer shr 4;
  191.     PByte3 (@OutputBuffer)^.b1 := Byte (lByteBuffer);
  192.     Result := 1;
  193.    end;
  194.   else
  195.    Result := 0;
  196.  end;
  197. end;
  198. function TMIMECipher.DecodeString (const s: AnsiString): AnsiString;
  199. var
  200.  ByteBuffer, ByteBufferSpace: Cardinal;
  201.  l                  : Cardinal;
  202. begin
  203.   if Pointer (s) <> nil then
  204.   begin
  205.     l := Cardinal (Pointer (Cardinal (s) - 4)^);
  206.     SetLength (Result, (l + 3) div 4 * 3);
  207.     ByteBuffer := 0;
  208.     ByteBufferSpace := 4;
  209.     l := MimeDecodePartial (Pointer (s)^, l, Pointer (Result)^, ByteBuffer, ByteBufferSpace);
  210.     Inc (l, MimeDecodePartialEnd (Pointer (Cardinal (Result) + l)^,
  211.       ByteBuffer, ByteBufferSpace));
  212.     SetLength (Result, l);
  213.   end
  214.   else
  215.   Result := '';
  216. end;
  217. procedure TMIMECipher.MimeEncodeNoCRLF (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  218. var
  219.   b, OuterLimit      : Cardinal;
  220.   InPtr, InnerLimit  : ^Byte;
  221.   OutPtr             : PByte4;
  222. begin
  223.   if InputByteCount = 0 then Exit;
  224.   InPtr := @InputBuffer;
  225.   OutPtr := @OutputBuffer;
  226.   OuterLimit := InputByteCount div 3 * 3;
  227.   InnerLimit := @InputBuffer;
  228.   Inc (Cardinal (InnerLimit), OuterLimit);
  229.   while InPtr <> InnerLimit do
  230.   begin
  231.     b := InPtr^;
  232.     b := b shl 8;
  233.     Inc (InPtr);
  234.     b := b or InPtr^;
  235.     b := b shl 8;
  236.     Inc (InPtr);
  237.     b := b or InPtr^;
  238.     Inc (InPtr);
  239.     OutPtr^.b4 := MIME_ENCODE_TABLE[b and $3F];
  240.     b := b shr 6;
  241.     OutPtr^.b3 := MIME_ENCODE_TABLE[b and $3F];
  242.     b := b shr 6;
  243.     OutPtr^.b2 := MIME_ENCODE_TABLE[b and $3F];
  244.     b := b shr 6;
  245.     OutPtr^.b1 := MIME_ENCODE_TABLE[b];
  246.     Inc (OutPtr);
  247.   end;
  248.   case InputByteCount - OuterLimit of
  249.     1:
  250.       begin
  251.         b := InPtr^;
  252.         b := b shl 4;
  253.         OutPtr.b2 := MIME_ENCODE_TABLE[b and $3F];
  254.         b := b shr 6;
  255.         OutPtr.b1 := MIME_ENCODE_TABLE[b];
  256.         OutPtr.b3 := MIME_PAD_CHAR;
  257.         OutPtr.b4 := MIME_PAD_CHAR;
  258.       end;
  259.     2:
  260.       begin
  261.         b := InPtr^;
  262.         Inc (InPtr);
  263.         b := b shl 8;
  264.         b := b or InPtr^;
  265.         b := b shl 2;
  266.         OutPtr.b3 := MIME_ENCODE_TABLE[b and $3F];
  267.         b := b shr 6;
  268.         OutPtr.b2 := MIME_ENCODE_TABLE[b and $3F];
  269.         b := b shr 6;
  270.         OutPtr.b1 := MIME_ENCODE_TABLE[b];
  271.         OutPtr.b4 := MIME_PAD_CHAR;         { Pad remaining byte. }
  272.       end;
  273.   end;
  274. end;
  275. function TMIMECipher.MimeEncodedSize (const i: Cardinal): Cardinal;
  276. begin
  277.   Result := (i + 2) div 3 * 4 + (i - 1) div MIME_DECODED_LINE_BREAK * 2;
  278. end;
  279. procedure TMIMECipher.MimeEncodeFullLines (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  280. var
  281.   b, OuterLimit      : Cardinal;
  282.   InPtr, InnerLimit  : ^Byte;
  283.   OutPtr             : PByte4;
  284. begin
  285.   if InputByteCount = 0 then Exit;
  286.   InPtr := @InputBuffer;
  287.   OutPtr := @OutputBuffer;
  288.   InnerLimit := InPtr;
  289.   Inc (Cardinal (InnerLimit), MIME_DECODED_LINE_BREAK);
  290.   OuterLimit := Cardinal (InPtr);
  291.   Inc (OuterLimit, InputByteCount);
  292.   while Cardinal (InnerLimit) <= OuterLimit do
  293.   begin
  294.     while InPtr <> InnerLimit do
  295.     begin
  296.      b := InPtr^;
  297.      b := b shl 8;
  298.      Inc (InPtr);
  299.      b := b or InPtr^;
  300.      b := b shl 8;
  301.      Inc (InPtr);
  302.      b := b or InPtr^;
  303.      Inc (InPtr);
  304.      OutPtr^.b4 := MIME_ENCODE_TABLE[b and $3F];
  305.      b := b shr 6;
  306.      OutPtr^.b3 := MIME_ENCODE_TABLE[b and $3F];
  307.      b := b shr 6;
  308.      OutPtr^.b2 := MIME_ENCODE_TABLE[b and $3F];
  309.      b := b shr 6;
  310.      OutPtr^.b1 := MIME_ENCODE_TABLE[b];
  311.      Inc (OutPtr);
  312.     end;
  313.     OutPtr^.b1 := 13;
  314.     OutPtr^.b2 := 10;
  315.     Inc (Cardinal (OutPtr), 2);
  316.     Inc (InnerLimit, MIME_DECODED_LINE_BREAK);
  317.   end;
  318. end;
  319. procedure TMIMECipher.MimeEncode (const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
  320. var
  321.   IDelta, ODelta     : Cardinal;
  322. begin
  323.   MimeEncodeFullLines (InputBuffer, InputByteCount, OutputBuffer);
  324.   IDelta := InputByteCount div MIME_DECODED_LINE_BREAK;
  325.  ODelta := IDelta * (MIME_ENCODED_LINE_BREAK + 2);
  326.  IDelta := IDelta * MIME_DECODED_LINE_BREAK;
  327.  MimeEncodeNoCRLF (Pointer (Cardinal (@InputBuffer) + IDelta)^,
  328.  InputByteCount - IDelta, Pointer (Cardinal (@OutputBuffer) + ODelta)^);
  329. end;
  330. function TMIMECipher.EncodeString (const s: AnsiString): AnsiString;
  331. var
  332.  l                  : Cardinal;
  333. begin
  334.   if Pointer (s) <> nil then
  335.   begin
  336.     l := Cardinal (Pointer (Cardinal (s) - 4)^);
  337.     SetLength (Result, MimeEncodedSize (l));
  338.     MimeEncode (Pointer (s)^, l, Pointer (Result)^);
  339.   end
  340.   else
  341.     Result := '';
  342. end;
  343. end.