unit base64;

interface

function base64decode(instr : string): string;
function base64encode(instr : string) : string;

implementation

uses
  SysUtils,classes;

function base64decode(instr : string) : string;
var
  inidx ,len: integer;
  outstr : String;
  in1, in2, in3, in4 : char;
  v1, v2, v3, v4 : integer;
  out1, out2, out3 : char;

  function ct(inchar : char) : integer;
  begin
    ct := 0;
    case inchar of
    'A' : ct :=  0 ;  'B' : ct :=  1 ;  'C' : ct :=  2 ;  'D' : ct :=  3 ;
    'E' : ct :=  4 ;  'F' : ct :=  5 ;  'G' : ct :=  6 ;  'H' : ct :=  7 ;
    'I' : ct :=  8 ;  'J' : ct :=  9 ;  'K' : ct := 10 ;  'L' : ct := 11 ;
    'M' : ct := 12 ;  'N' : ct := 13 ;  'O' : ct := 14 ;  'P' : ct := 15 ;
    'Q' : ct := 16 ;  'R' : ct := 17 ;  'S' : ct := 18 ;  'T' : ct := 19 ;
    'U' : ct := 20 ;  'V' : ct := 21 ;  'W' : ct := 22 ;  'X' : ct := 23 ;
    'Y' : ct := 24 ;  'Z' : ct := 25 ;  'a' : ct := 26 ;  'b' : ct := 27 ;
    'c' : ct := 28 ;  'd' : ct := 29 ;  'e' : ct := 30 ;  'f' : ct := 31 ;
    'g' : ct := 32 ;  'h' : ct := 33 ;  'i' : ct := 34 ;  'j' : ct := 35 ;
    'k' : ct := 36 ;  'l' : ct := 37 ;  'm' : ct := 38 ;  'n' : ct := 39 ;
    'o' : ct := 40 ;  'p' : ct := 41 ;  'q' : ct := 42 ;  'r' : ct := 43 ;
    's' : ct := 44 ;  't' : ct := 45 ;  'u' : ct := 46 ;  'v' : ct := 47 ;
    'w' : ct := 48 ;  'x' : ct := 49 ;  'y' : ct := 50 ;  'z' : ct := 51 ;
    '0' : ct := 52 ;  '1' : ct := 53 ;  '2' : ct := 54 ;  '3' : ct := 55 ;
    '4' : ct := 56 ;  '5' : ct := 57 ;  '6' : ct := 58 ;  '7' : ct := 59 ;
    '8' : ct := 60 ;  '9' : ct := 61 ;  '+' : ct := 62 ;  '/' : ct := 63 ;
    end;
  end;

begin
   try
     inidx := 1;
     len := Length ( instr);
     outstr := '';
     while  inidx < len do
     begin
       in1 := instr[inidx];
       inc(inidx);
       in2 := instr[inidx];
       inc(inidx);
       in3 := instr[inidx];
       inc(inidx);
       in4 := instr[inidx];
       inc(inidx);

       if instr[inidx] = #13 then
       begin
         inidx := inidx+2;
       end;

       v1 := ct(in1);
       v2 := ct(in2);
       v3 := ct(in3);
       v4 := ct(in4);

       if ((in3 = '=') and (in4 = '=')) then
       begin
         out1 := chr((v1 shl 2)+(v2 shr 4));
         outstr := concat(outstr,out1);
         break;
       end
       else if ((in3 <> '=') and (in4 = '=')) then
       begin
         out1 := chr((v1 shl 2)+(v2 shr 4));
         out2 := chr((v2 shl 4)+(v3 shr 2));
         outstr := concat(outstr,out1);
         outstr := concat(outstr,out2);
         break;
       end
       else
       begin
         out1 := chr((v1 shl 2)+(v2 shr 4));
         out2 := chr((v2 shl 4)+(v3 shr 2));
         out3 := chr((v3 shl 6)+v4);
         outstr := concat(outstr,out1);
         outstr := concat(outstr,out2);
         outstr := concat(outstr,out3);
       end;
     end;
   finally
     result := outstr;
   end;
end;

function base64encode(instr : string): string;
var
  inidx,len : integer;
  outstr : String;
  nsize : longInt;
  in1, in2, in3, t : char;
  out1, out2, out3, out4 : integer;
  index, final : integer;
  tmpstr : String;

  function ct(inchar : integer) : char;
  begin
    ct := ' ';
    case inchar of
     0 : ct := 'A' ;   1 : ct := 'B' ;   2 : ct := 'C' ;   3 : ct := 'D' ;
     4 : ct := 'E' ;   5 : ct := 'F' ;   6 : ct := 'G' ;   7 : ct := 'H' ;
     8 : ct := 'I' ;   9 : ct := 'J' ;  10 : ct := 'K' ;  11 : ct := 'L' ;
    12 : ct := 'M' ;  13 : ct := 'N' ;  14 : ct := 'O' ;  15 : ct := 'P' ;
    16 : ct := 'Q' ;  17 : ct := 'R' ;  18 : ct := 'S' ;  19 : ct := 'T' ;
    20 : ct := 'U' ;  21 : ct := 'V' ;  22 : ct := 'W' ;  23 : ct := 'X' ;
    24 : ct := 'Y' ;  25 : ct := 'Z' ;  26 : ct := 'a' ;  27 : ct := 'b' ;
    28 : ct := 'c' ;  29 : ct := 'd' ;  30 : ct := 'e' ;  31 : ct := 'f' ;
    32 : ct := 'g' ;  33 : ct := 'h' ;  34 : ct := 'i' ;  35 : ct := 'j' ;
    36 : ct := 'k' ;  37 : ct := 'l' ;  38 : ct := 'm' ;  39 : ct := 'n' ;
    40 : ct := 'o' ;  41 : ct := 'p' ;  42 : ct := 'q' ;  43 : ct := 'r' ;
    44 : ct := 's' ;  45 : ct := 't' ;  46 : ct := 'u' ;  47 : ct := 'v' ;
    48 : ct := 'w' ;  49 : ct := 'x' ;  50 : ct := 'y' ;  51 : ct := 'z' ;
    52 : ct := '0' ;  53 : ct := '1' ;  54 : ct := '2' ;  55 : ct := '3' ;
    56 : ct := '4' ;  57 : ct := '5' ;  58 : ct := '6' ;  59 : ct := '7' ;
    60 : ct := '8' ;  61 : ct := '9' ;  62 : ct := '+' ;  63 : ct := '/' ;
    end;
  end;

begin
   outstr := '';
   try
       inidx := 1;
       len := length(instr);
       nsize := 0;
       index := 0;

       while (nsize < len) do
        begin
           inc(nsize);
           in1 := instr[inidx];
           inc(inidx);
           final := 8;
          if (nsize < len) then
           begin
             inc(nsize);
             in2 := instr[inidx];
             inc(inidx);

             final := 16;
           end
          else in2 := chr(0);

          if (nsize < len) then
           begin
             inc(nsize);
             in3 := instr[inidx];
             inc(inidx);

             final := 24;
           end
          else in3 := chr(0);

          out1 := ord(in1) shr 2;
          out2 := ((ord(in1) and 3) shl 4) + (ord(in2) shr 4);
          out3 := ((ord(in2) and 15) shl 2) + ((ord(in3) and 192) shr 6);
          out4 := ord(in3) and 63;

          t := ct(out1);
          inc(index);
          outstr := concat(outstr,t);

          t := ct(out2);
          inc(index);
         outstr := concat(outstr,t);

          if ((final = 8) and (nsize = len)) then
          begin
            tmpstr := '=='+#$D+#$A;
            outstr := concat(outstr,tmpstr);
            break;
          end;
          t := ct(out3);
          inc(index);
          outstr := concat(outstr,t);

          if ((final = 16) and (nsize = len)) then
          begin
            tmpstr := '='+#$D+#$A;
            outstr := concat(outstr,tmpstr);
            break;
          end;

          t := ct(out4);
          inc(index);
          outstr := concat(outstr,t);
          if index = 72 then
          begin
            tmpstr := #$D+#$A;
            outstr := concat(outstr,tmpstr);
            index := 0;
          end;

        end;
   finally
   result := outstr;
   end;
end;

end.
