Utbase64.pas
上传用户:lzd18710
上传日期:2009-11-26
资源大小:3595k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual Basic

  1. unit uTBase64;
  2. // uTBase64 v1.0 - Simple Base64 encoding/decoding class
  3. // Base64 described in RFC2045, Page 24, (w) 1996 Freed & Borenstein
  4. // Delphi implementation (w) 1999 Dennis D. Spreen (dennis@spreendigital.de)
  5. // This unit is freeware. Just drop me a line if this unit is useful for you.
  6. //
  7. // methods:
  8. //  function EncodeData(InputData:string;var OutputData:string):byte;
  9. //   return values:
  10. //    BASE64_OK    = no errors, conversion successful
  11. //    BASE64_ERROR = unknown error (e.g. can't encode octet in input stream) -> error in implementation
  12. //
  13. //  function DecodeData(InputData:string;var OutputData:string):byte;
  14. //   return values:
  15. //    BASE64_OK       = no errors, conversion successful
  16. //    BASE64_INVALID  = invalid characters in input string (may occur only when filterdecodeinput=false)
  17. //    BASE64_LENGTH   = input data length is not a Base64 length (mod 4)
  18. //    BASE64_DATALEFT = too much input data left (receveived 'end of encoded data' but not end of input string)
  19. //    BASE64_PADDING  = wrong padding (input data isn't closed with correct padding characters)
  20. //
  21. //  properties:
  22. //     filterdecodeinput:boolean;  //delete all forbidden characters in input stream: Default=true
  23. //
  24. //  note for Delphi 1 users:
  25. //   as with delphi 1 the max. length of a string can not exceed the length of 255 byte,
  26. //   you may experience some problems (=errors) whilst encoding/decoding such lines.
  27. //   but as base64 is commonly used as internet mail encoding for which the maximum
  28. //   line size is 76 chars (=57 decoded chars) the use of this unit is not problematic.
  29. //
  30. // example:
  31. //  var Base64:TBase64;
  32. //       s1,s2:string;
  33. //  begin
  34. //   Base64:=TBase64.Create;
  35. //   s1:='this needs to be Base64-encoded';
  36. //   Base64.EncodeData(s1,s2);
  37. //   ShowMessage('Encoded string:'+s2);
  38. //   s1:='';
  39. //   Base64.DecodeData(s2,s1);
  40. //   ShowMessage('Decoded string:'+s1);
  41. //   Base64.Free;
  42. //  end;
  43. //
  44. interface
  45. uses sysUtils;
  46. type TBase64 = class(TObject)
  47.      private
  48.       ffilterdecodeinput:boolean;
  49.       function ValueToCharacter(value:Byte;var character:char):boolean;
  50.       function CharacterToValue(character:char;var value:byte):boolean;
  51.       function filterLine(InputData:string):string;
  52.      protected
  53.      public
  54.       function EncodeData(InputData:string;var OutputData:string):Byte;
  55.       function DecodeData(InputData:string;var OutputData:string):Byte;
  56.       constructor Create;
  57.      published
  58.       property filterdecodeinput:boolean read ffilterdecodeinput write ffilterdecodeinput;
  59.      end;
  60. const BASE64_OK       = 0; // no errors, conversion successful
  61.       BASE64_ERROR    = 1; // unknown error (e.g. can't encode octet in input stream) -> error in implementation
  62.       BASE64_INVALID  = 2; // invalid characters in input string (may occur only when filterdecodeinput=false)
  63.       BASE64_LENGTH   = 3; // input data length is not a Base64 length (mod 4)
  64.       BASE64_DATALEFT = 4; // too much input data left (receveived 'end of encoded data' but not end of input string)
  65.       BASE64_PADDING  = 5; // wrong padding (input data isn't closed with correct padding characters)
  66. procedure EncodeData64(var s:string);
  67. procedure DecodeData64(var s:string);
  68. function code64(s: string; encode: boolean): string;
  69. implementation
  70. function code64(s: string; encode: boolean): string;
  71. var
  72.   Base64: TBase64;
  73.   s2:string;
  74. begin
  75.   Base64:=TBase64.Create;
  76.   try
  77.     if encode then
  78.       Base64.EncodeData(s,s2)
  79.     else
  80.       Base64.DecodeData(s,s2);
  81.     result := s2;
  82.   finally
  83.     Base64.Free;
  84.   end;
  85. end;
  86. procedure EncodeData64(var s:string);
  87. var Base64:TBase64;
  88.      s1:string;
  89. begin
  90.   Base64:=TBase64.Create;
  91.   try
  92.     Base64.EncodeData(s,s1);
  93.     s := s1;
  94.   finally
  95.     Base64.Free;
  96.   end;
  97. end;
  98. procedure DecodeData64(var s:string);
  99. var Base64:TBase64;
  100.      s1:string;
  101. begin
  102.   Base64:=TBase64.Create;
  103.   try
  104.     Base64.DecodeData(s,s1);
  105.     s := s1;
  106.   finally
  107.     Base64.Free;
  108.   end;
  109. end;
  110. const AlphabetLength = 64;
  111.       Alphabet:string[AlphabetLength]='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  112.       Pad = '=';
  113. constructor TBase64.Create;
  114. begin
  115.  inherited Create;
  116.  ffilterdecodeinput:=true;
  117. end;
  118. //******************************************************************
  119. // converts a value in the range of 0..AlphabetLength-1 to the
  120. // corresponding base64 alphabet representation
  121. // returns true if the value is in the alphabet range
  122. //******************************************************************
  123. function TBase64.ValueToCharacter(value:Byte;var character:char):boolean;
  124. begin
  125.  Result:=true;
  126.  if (value>AlphabetLength-1) then Result:=false
  127.                              else character:=Alphabet[value+1];
  128. end;
  129. //******************************************************************
  130. // converts a character to a value in the range of 0..AlphabetLength-1
  131. // returns true if the character exists in the alphabet
  132. //******************************************************************
  133. function TBase64.CharacterToValue(character:char;var value:byte):boolean;
  134. begin
  135.  Result:=true;
  136.  value:=Pos(character,Alphabet);
  137.  if value=0 then Result:=false
  138.             else value:=value-1;
  139. end;
  140. //******************************************************************
  141. // Encodes a string to its base64 representation in ASCII Format
  142. // returns BASE64_OK if conversion was done without errors
  143. //******************************************************************
  144. function TBase64.EncodeData(InputData:string;var OutputData:string):Byte;
  145. var i:integer;
  146.     currentb,prevb:Byte;
  147.     c:Byte;
  148.     s:char;
  149.     InputLength:integer;
  150. begin
  151.  OutPutData:='';
  152.  InputLength:=Length(InputData);
  153.  i:=1;
  154.  if (InputLength=0) then begin Result:=BASE64_OK;exit;end;
  155.  repeat
  156.   // process first group
  157.   currentb:=ord(InputData[i]);
  158.   i:=i+1;
  159.   InputLength:=InputLength-1;
  160.   c:=(currentb shr 2);
  161.   if not ValueToCharacter(c,s) then begin Result:=BASE64_ERROR;exit;end;
  162.   OutPutData:=OutPutData+s;
  163.   prevb:=currentb;
  164.   // process second group
  165.   if InputLength=0 then currentb:=0
  166.               else begin
  167.                     currentb:=ord(InputData[i]);
  168.                     i:=i+1;
  169.                    end;
  170.   InputLength:=InputLength-1;
  171.   c:=(prevb and $03) shl 4 + (currentb shr 4);
  172.   if not ValueToCharacter(c,s) then begin Result:=BASE64_ERROR;exit;end;
  173.   OutPutData:=OutPutData+s;
  174.   prevb:=currentb;
  175.   // process third group
  176.   if InputLength<0 then s:=pad
  177.                    else
  178.    begin
  179.     if InputLength=0 then currentb:=0
  180.               else begin
  181.                     currentb:=ord(InputData[i]);
  182.                     i:=i+1;
  183.                    end;
  184.     InputLength:=InputLength-1;
  185.     c:=(prevb and $0F) shl 2 + (currentb shr 6);
  186.     if not ValueToCharacter(c,s) then begin Result:=BASE64_ERROR;exit;end;
  187.    end;
  188.   OutPutData:=OutPutData+s;
  189.   // process fourth group
  190.   if InputLength<0 then s:=pad
  191.                     else
  192.                     begin
  193.                      c:=(currentb and $3F);
  194.                      if not ValueToCharacter(c,s) then begin Result:=BASE64_ERROR;exit;end;
  195.                     end;
  196.   OutPutData:=OutPutData+s;
  197.  until InputLength<=0;
  198.  result:=BASE64_OK;
  199. end;
  200. //******************************************************************
  201. // ignores all characters not in base64 alphabet
  202. // and returns the filtered string
  203. //******************************************************************
  204. function TBase64.filterLine(InputData:string):string;
  205. var f:byte;
  206.     i:integer;
  207. begin
  208.    result:='';
  209.    for i:= 1 to Length(InputData) do
  210.     if CharacterToValue(inputData[i],f) or (InputData[i]=Pad) then result:=Result+InputData[i];
  211. end;
  212. //******************************************************************
  213. // Decodes a base64 representation in ASCII format into a string
  214. // returns BASE64_OK if conversion was done without errors
  215. //******************************************************************
  216. function TBase64.DecodeData(InputData:string;var OutputData:string):Byte;
  217. var i:integer;
  218.     InputLength:integer;
  219.     currentb,prevb:Byte;
  220.     c:Byte;
  221.     s:char;
  222. begin
  223.  if (InputData='') then begin result:=BASE64_OK;exit;end;
  224.  OutPutData:='';
  225.  if filterdecodeinput then InputData:=FilterLine(InputData);
  226.  InputLength:=Length(InputData);
  227.  if InputLength mod 4<>0 then begin Result:=BASE64_LENGTH;exit;end;
  228.  i:=0;
  229.  repeat
  230.     // process first byte
  231.     i:=i+1;s:=InputData[i];  if not CharacterToValue(s,currentb) then begin Result:=BASE64_INVALID;exit;end;
  232.     i:=i+1;s:=InputData[i];  if not CharacterToValue(s,prevb)    then begin Result:=BASE64_INVALID;exit;end;
  233.     c:=(currentb shl 2)+(prevb shr 4);
  234.     OutPutData:=OutPutData+chr(c);
  235.     // process second Byte
  236.     i:=i+1;s:=InputData[i];
  237.     if s=pad then
  238.       begin
  239.        if (i<>InputLength-1) then begin Result:=BASE64_DATALEFT;exit;end // too much data left
  240.                                   else if InputData[i+1]<>pad then begin Result:=BASE64_PADDING;exit;end; // last char has to be a pad
  241.       end
  242.       else
  243.       begin
  244.        if not CharacterToValue(s,currentb) then begin Result:=BASE64_INVALID;exit;end;
  245.        c:=(prevb shl 4)+(currentb shr 2);
  246.        OutPutData:=OutPutData+chr(c);
  247.       end;
  248.     // process third Byte
  249.    i:=i+1;s:=InputData[i];
  250.    if s=pad then
  251.     begin
  252.      if (i<>InputLength) then begin Result:=BASE64_DATALEFT;exit;end; // too much data Left
  253.     end
  254.     else
  255.     begin
  256.      if not CharacterToValue(s,prevb) then begin Result:=BASE64_INVALID;exit;end;
  257.      c:=(currentb shl 6)+(prevb);
  258.      OutPutData:=OutPutData+chr(c);
  259.     end;
  260.  until (i>=InputLength);
  261.  result:=BASE64_OK;
  262. end;
  263. end.