delphi NM64Encode.pas NM64Decode.pas  
官方Delphi 学习QQ群: 682628230(三千人)
频道

delphi NM64Encode.pas NM64Decode.pas


[Quote title="NM64Encode.pas"]unit NM64Encode;

interface
uses
  Classes;

function B64Encode(const source, destination: TStream): Boolean;

implementation
uses
  NMFileBuffer;

var
  B64Table: array[0..63] of Char =
  ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
    'w', 'x', 'y', 'z', '0', '1', '2', '3',
    '4', '5', '6', '7', '8', '9', '+', '/');

function B64Encode(const source, destination: TStream): Boolean;
var
  Counter: LongInt;
  TotalBytes: LongInt;

  EOD: Char;
  B64Char: Char;
  Char1: Char;
  Char2: Char;
  Char3: Char;

  InputPtr, OutputPtr, BufferEnd: PChar;

  MemStuff: TNMFileBuffer;

  Output: string;
  Len: Integer;
begin
  Counter := 0;
  TotalBytes := source.Size;

  EOD := '=';
  Len := 62;
  Output := '';
  SetLength(Output, Len);
  OutputPtr := PChar(Output);

  destination.Seek(0, soFromEnd);

  MemStuff := TNMFileBuffer.Create(source);
  try
    InputPtr := MemStuff.BufPos;
    BufferEnd := MemStuff.BufEnd;
    while True do
    begin
      if InputPtr >= BufferEnd then
        if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
          Break
        else
        begin
          InputPtr := MemStuff.BufPos;
          BufferEnd := MemStuff.BufEnd;
        end;
      Char1 := InputPtr^;
      inc(InputPtr);
      B64Char := B64Table[Byte(Char1) shr 2];
      OutputPtr^ := B64Char;
      inc(OutputPtr);
      inc(Counter);

      if Counter >= TotalBytes then
      begin
        Char2 := #0;
        B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))];
        OutputPtr^ := B64Char;
        inc(OutputPtr);
        OutputPtr^ := EOD;
        inc(OutputPtr);
        OutputPtr^ := EOD;
        inc(OutputPtr);
      end
      else
      begin
        if InputPtr >= BufferEnd then
          if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
            Break
          else
          begin
            InputPtr := MemStuff.BufPos;
            BufferEnd := MemStuff.BufEnd;
          end;
        Char2 := InputPtr^;
        inc(InputPtr);
        B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))];
        OutputPtr^ := B64Char;
        inc(OutputPtr);
        inc(Counter);

        if Counter >= TotalBytes then
        begin
          Char3 := #0;
          B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))];
          OutputPtr^ := B64Char;
          inc(OutputPtr);
          OutputPtr^ := EOD;
          inc(OutputPtr);
        end
        else
        begin
          if InputPtr >= BufferEnd then
            if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
              Break
            else
            begin
              InputPtr := MemStuff.BufPos;
              BufferEnd := MemStuff.BufEnd;
            end;
          Char3 := InputPtr^;
          inc(InputPtr);
          B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))];
          OutputPtr^ := B64Char;
          inc(OutputPtr);
          inc(Counter);
          B64Char := B64Table[(Byte(Char3) and $3F)];
          OutputPtr^ := B64Char;
          inc(OutputPtr);
        end;
      end;

      if (Counter mod 45 = 0) or ((OutputPtr - 1)^ = EOD) then
      begin
        if ((OutputPtr - 1)^ <> EOD) then
        begin
          OutputPtr^ := #13;
          inc(OutputPtr);
          OutputPtr^ := #10;
          inc(OutputPtr);
          OutputPtr^ := #0;
        end
        else
        begin
          Len := LongInt(OutputPtr) - LongInt(Output);
          SetLength(Output, Len);
        end;
        destination.Write(PChar(Output)^, Len);
        OutputPtr := PChar(Output);
      end;
    end;
  finally
    MemStuff.Free;
  end;

  Len := LongInt(OutputPtr) - LongInt(Output);
  if Len > 0 then
  begin
    SetLength(Output, Len);
    destination.Write(PChar(Output)^, Len);
  end;

  destination.Write(EOD, 1);
  result := True;
end;

end.
[/Quote]


[Quote title="NM64Decode.pas"]unit NM64Decode;

interface
uses
  Classes;

function B64Decode(const Source: TStream; var Destination: TStream): Boolean;

implementation
uses
  sysutils;

const
  INVALID = $FF;

var
  B64_Table: array[0..255] of Byte;

function B64Decode(const Source: TStream; var Destination: TStream): Boolean;
const
  EOD = '=';
  EOB = $FE;
  INVALID = $FF;
  CR = #13;
  LF = #10;
  EOL = #0;

var
  Stream_Ptr: PChar;

  procedure Decode;
  var
    Char1: Byte;
    Char2: Byte;
    Char3: Byte;
    Char4: Byte;
    Count: Integer;

    Line_Ptr: PChar;
    Line_Length: LongInt;
    Line: string;
  begin
    Line_Length := StrLen(Stream_Ptr) * 3 div 4;
    SetLength(Line, Line_Length);
    Line_Ptr := PChar(Line);

    while Line_Length > 0 do
    begin
      Count := 0;
      if Stream_Ptr^ > EOL then
      begin
        Char1 := B64_Table[Byte(Stream_Ptr^)];
        Inc(Stream_Ptr);
      end
      else
        Char1 := INVALID;

      if Stream_Ptr^ > EOL then
      begin
        Char2 := B64_Table[Byte(Stream_Ptr^)];
        Inc(Stream_Ptr);
      end
      else
        Char2 := INVALID;

      if Stream_Ptr^ > EOL then
      begin
        Char3 := B64_Table[Byte(Stream_Ptr^)];
        Inc(Stream_Ptr);
      end
      else
        Char3 := INVALID;

      if Stream_Ptr^ > EOL then
      begin
        Char4 := B64_Table[Byte(Stream_Ptr^)];
        Inc(Stream_Ptr);
      end
      else
        Char4 := INVALID;

      if (Char1 = INVALID) or (Char2 = INVALID) then
        raise Exception.Create('Invalid data encountered within stream')
      else
      begin
        Line_Ptr^ := Char((Char1 shl 2) or ((Char2 and $30) shr 4));
        Inc(Line_Ptr);
        Inc(Count);

        if (Char3 <> INVALID) then
        begin
          Line_Ptr^ := Char(((Char2 and $0F) shl 4) or ((Char3 and $3C) shr 2));
          Inc(Line_Ptr);
          Inc(Count);

          if (Char4 <> INVALID) then
          begin
            Line_Ptr^ := Char(((Char3 and $03) shl 6) or (Char4));
            Inc(Line_Ptr);
            Inc(Count);
          end;
        end
      end;
      Dec(Line_Length, Count);
    end;
    Destination.Write(Pointer(Line)^, Line_Ptr - PChar(Line));
  end;

const
  MaxBufSize = $FFFE;

var
  Buffer, FillPos, BufPos: PChar;
  Counter, BytesRead: LongInt;
  SourceSize: LongInt;
begin
  Result := TRUE;

//  InitTable;

  SourceSize := Source.Size;
  Destination.Seek(0, soFromEnd);

  Counter := 0;

  GetMem(Buffer, MaxBufSize + 1);
  FillPos := Buffer;
  BufPos := Buffer;
  Inc(FillPos, MaxBufSize + 1);
  FillPos^ := EOL;
  try
    while (Source.Position < SourceSize) and (BufPos^ <> EOD) do
    begin
      FillPos := Buffer;
      Inc(FillPos, Counter);
      BytesRead := Source.Read(FillPos^, MaxBufSize - Counter);
      Inc(Counter, BytesRead);
      BufPos := Buffer;
      Inc(FillPos, Counter);
      FillPos^ := EOL;
      Counter := 0;
      while (BufPos^ <> EOL) do
      begin
        Stream_Ptr := BufPos;
        while not (BufPos^ in [EOL, LF, CR, EOD]) do
          Inc(BufPos);
        if (BufPos^ <> EOL) or (BufPos^ = EOD) then
        begin
          BufPos^ := EOL;
          Decode;
          if BufPos^ = EOL then Inc(BufPos);
          if BufPos^ = CR then Inc(BufPos);
          if BufPos^ = LF then Inc(BufPos);
        end
        else
        begin
          Counter := BufPos - Stream_Ptr;
          System.Move(Stream_Ptr^, Buffer^, Counter);
          Break;
        end;
      end;
    end;
    if Counter > 0 then
    begin
      Stream_Ptr := Buffer;
      Decode;
    end;
  finally
    FreeMem(Buffer, MaxBufSize);
  end;
end;

initialization
  begin
    FillChar(B64_Table, SizeOf(B64_Table), INVALID);

    B64_Table[43] := 62;
    B64_Table[47] := 63;
    B64_Table[48] := 52;
    B64_Table[49] := 53;
    B64_Table[50] := 54;
    B64_Table[51] := 55;
    B64_Table[52] := 56;
    B64_Table[53] := 57;
    B64_Table[54] := 58;
    B64_Table[55] := 59;
    B64_Table[56] := 60;
    B64_Table[57] := 61;
    B64_Table[65] := 0;
    B64_Table[66] := 1;
    B64_Table[67] := 2;
    B64_Table[68] := 3;
    B64_Table[69] := 4;
    B64_Table[70] := 5;
    B64_Table[71] := 6;
    B64_Table[72] := 7;
    B64_Table[73] := 8;
    B64_Table[74] := 9;
    B64_Table[75] := 10;
    B64_Table[76] := 11;
    B64_Table[77] := 12;
    B64_Table[78] := 13;
    B64_Table[79] := 14;
    B64_Table[80] := 15;
    B64_Table[81] := 16;
    B64_Table[82] := 17;
    B64_Table[83] := 18;
    B64_Table[84] := 19;
    B64_Table[85] := 20;
    B64_Table[86] := 21;
    B64_Table[87] := 22;
    B64_Table[88] := 23;
    B64_Table[89] := 24;
    B64_Table[90] := 25;
    B64_Table[97] := 26;
    B64_Table[98] := 27;
    B64_Table[99] := 28;
    B64_Table[100] := 29;
    B64_Table[101] := 30;
    B64_Table[102] := 31;
    B64_Table[103] := 32;
    B64_Table[104] := 33;
    B64_Table[105] := 34;
    B64_Table[106] := 35;
    B64_Table[107] := 36;
    B64_Table[108] := 37;
    B64_Table[109] := 38;
    B64_Table[110] := 39;
    B64_Table[111] := 40;
    B64_Table[112] := 41;
    B64_Table[113] := 42;
    B64_Table[114] := 43;
    B64_Table[115] := 44;
    B64_Table[116] := 45;
    B64_Table[117] := 46;
    B64_Table[118] := 47;
    B64_Table[119] := 48;
    B64_Table[120] := 49;
    B64_Table[121] := 50;
    B64_Table[122] := 51;
  end;

end.
[/Quote]
推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.035664081573486 seconds