Recent

Author Topic: [SOLVED] XOREncode and XORDecode files using TFileStream  (Read 1630 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
[SOLVED] XOREncode and XORDecode files using TFileStream
« on: May 22, 2018, 02:07:25 pm »
Hi

Am trying to write a simple XOREncode and XORDecode of files, using FileStreams.

The following almost works, in that it compiles and the XOREncode seems to work (the output looks like a valid XOR'd text file). But the decode fails to successfully decode.

When I run through it with the debugger, the variable XORData seems to jump between legible decoded text first pass, illegible second pass, legible third pass, illegible forth pass, and so on. I can't see where I am going wrong? Can anyone direct me? I am suspecting it has something to do with unprintable characters, but given that I am feeding the program text files, I'm not sure why this would be happening.

Thanks

Code: Pascal  [Select][+][-]
  1. // Encode a plain text file
  2. procedure TForm1.btnInputFileClick(Sender: TObject);
  3. var
  4.   FileToEncode : string;
  5.   OutputFile   : string;
  6.   Key          : string;
  7.   XORData      : string;
  8.   fIn, fOut    : TFileStream;
  9.   Buffer       : array [0..65534] of char;
  10.   TotalBytesRead : Int64;
  11.   BinaryBytesRead : integer;
  12. begin
  13.   TotalBytesRead := 0;
  14.   BinaryBytesRead := 0;
  15.   Label2.Caption:= ' Encoding...';
  16.   Key := ledtPasswordFile.Text;  // takes the password key from the user input field
  17.   FillChar(Buffer,SizeOf(Buffer),0);
  18.  
  19.   if odInputFile.Execute then
  20.   begin
  21.   // Get inputfile
  22.   FileToEncode := odInputFile.FileName;
  23.   // Get output file
  24.   if sdOutFile.Execute then
  25.     begin
  26.     OutputFile := sdOutFile.FileName;
  27.     // Read input file in buffers
  28.       try
  29.         fIn := TFileStream.Create(FileToEncode, fmOpenRead);
  30.         fIn.Position := 0;
  31.         try
  32.           // Encode and write out Output file in buffers
  33.           fOut := TFileStream.create(OutputFile, fmCreate);
  34.           fOut.Position := 0;
  35.           while (TotalBytesRead < fIn.Size) do
  36.             begin
  37.               BinaryBytesRead := fIn.Read(Buffer[0], SizeOf(Buffer));
  38.               if BinaryBytesRead > -1 then
  39.                 begin
  40.                   XORData := XorEncode(Key, Buffer);
  41.                   fOut.Write(XORData[1], Length(XORData));
  42.                 end;
  43.               inc(TotalBytesRead, BinaryBytesRead);
  44.             end;
  45.         finally
  46.           fOut.Free;
  47.         end;
  48.       finally
  49.         fIn.Free;
  50.       end;
  51.     end;
  52.   end;
  53.   Label2.Caption:= ' Finished.';
  54. end;
  55.  
  56. // Decode an XOREncoded file
  57. procedure TForm1.btnDecodeFileClick(Sender: TObject);
  58. var
  59.   FileToDecode : string;
  60.   OutputFile   : string;
  61.   Key          : string;
  62.   XORData      : string;
  63.   fIn, fOut    : TFileStream;
  64.   Buffer       : array [0..65534] of char;
  65.   TotalBytesRead : Int64;
  66.   BinaryBytesRead : integer;
  67. begin
  68.   TotalBytesRead := 0;
  69.   BinaryBytesRead := 0;
  70.   Label2.Caption:= ' Decoding...';
  71.   Key := ledtPasswordFile.Text;   // takes the password key from the user input field
  72.   FillChar(Buffer,SizeOf(Buffer),0);
  73.  
  74.   if odInputFile.Execute then
  75.   begin
  76.   // Get inputfile
  77.   FileToDecode := odInputFile.FileName;
  78.   // Get output file
  79.   if sdOutFile.Execute then
  80.     begin
  81.     OutputFile := sdOutFile.FileName;
  82.     // Read input file in buffers
  83.       try
  84.         fIn := TFileStream.Create(FileToDecode, fmOpenRead);
  85.         fIn.Position := 0;
  86.         try
  87.           // Encode and write out Output file in buffers
  88.           fOut := TFileStream.create(OutputFile, fmCreate);
  89.           fOut.Position := 0;
  90.           while (TotalBytesRead < fIn.Size) do
  91.             begin
  92.               BinaryBytesRead := fIn.Read(Buffer[0], SizeOf(Buffer));
  93.               if BinaryBytesRead > -1 then
  94.                 begin
  95.                   XORData := XorDecode(Key, Buffer);
  96.                   fOut.Write(XORData[1], Length(XORData));
  97.                 end;
  98.               inc(TotalBytesRead, BinaryBytesRead);
  99.             end;
  100.         finally
  101.           fOut.Free;
  102.         end;
  103.       finally
  104.         fIn.Free;
  105.       end;
  106.     end;
  107.   end;
  108.   Label2.Caption:= ' Finished.';
  109. end;
  110.  
« Last Edit: May 22, 2018, 03:29:29 pm by Gizmo »

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: XOREncode and XORDecode files using TFileStream
« Reply #1 on: May 22, 2018, 02:23:38 pm »
That is terribly over-complex code.
Try string.ToCharArray, then do xor on the array. (sysutils)
If you can not figure it out, I will post a small example (less than 20 lines)
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: XOREncode and XORDecode files using TFileStream
« Reply #2 on: May 22, 2018, 02:49:12 pm »
I can't use ToCharArray with the Buffer I have as its an array of char and not a string. If I change buffer to type string, then I'm not sure how I can use FileStream.Read when the size will not be known? FS.ReadAnsiString might be btter but then what about non-ASCII chars?

Your example might be helpful if you have the time to share? I'd appreciate it.   

UPDATE : Resolved with following code (assumes the input files are not too big and small enough for memory I accept but gets over the streaming difficulty and it works). If anyone has a stream method that will work, I'd still welcome the example.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.btnInputFileClick(Sender: TObject);
  2. var
  3.   FileToEncode, OutputFile, Key, XORData, Buffer : string;
  4.   fIn, fOut    : TFileStream;
  5. begin
  6.   Label2.Caption := ' Encoding...';
  7.   Key            := ledtPasswordFile.Text;
  8.   Buffer         := '';
  9.  
  10.   if odInputFile.Execute then
  11.   begin
  12.   // Get inputfile
  13.   FileToEncode := odInputFile.FileName;
  14.   // Get output file
  15.   if sdOutFile.Execute then
  16.     begin
  17.     OutputFile := sdOutFile.FileName;
  18.     // Read input file in buffers
  19.       try
  20.         fIn := TFileStream.Create(FileToEncode, fmOpenRead);
  21.         fIn.Position := 0;
  22.         try
  23.           // Encode and write out Output file in buffers
  24.           fOut := TFileStream.create(OutputFile, fmCreate);
  25.           fOut.Position := 0;
  26.           try
  27.             SetLength(Buffer, fIn.Size);
  28.             fIn.Read(Buffer[1], fIn.Size);
  29.             XORData := XorEncode(Key, Buffer);
  30.             fOut.Write(XORData[1], Length(XORData));
  31.           finally
  32.           end;
  33.         finally
  34.          fOut.free;
  35.         end;
  36.       finally
  37.         fIn.Free;
  38.       end;
  39.     end;
  40.   end;
  41.   Label2.Caption:= ' Finished.';
  42. end;
  43.  
  44. procedure TForm1.btnDecodeFileClick(Sender: TObject);
  45. var
  46.   FileToDecode, OutputFile, Key, XORData, Buffer : string;
  47.   fIn, fOut    : TFileStream;
  48. begin
  49.   Label2.Caption := ' Decoding...';
  50.   Key            := ledtPasswordFile.Text;
  51.   Buffer         := '';
  52.  
  53.   if odInputFile.Execute then
  54.   begin
  55.   // Get inputfile
  56.   FileToDecode := odInputFile.FileName;
  57.   // Get output file
  58.   if sdOutFile.Execute then
  59.     begin
  60.     OutputFile := sdOutFile.FileName;
  61.     // Read input file in buffers
  62.       try
  63.         fIn := TFileStream.Create(FileToDecode, fmOpenRead);
  64.         fIn.Position := 0;
  65.         try
  66.           // Encode and write out Output file in buffers
  67.           fOut := TFileStream.create(OutputFile, fmCreate);
  68.           fOut.Position := 0;
  69.           try
  70.             SetLength(Buffer, fIn.Size);
  71.             fIn.Read(Buffer[1], fIn.Size);
  72.             XORData := XorDecode(Key, Buffer);
  73.             fOut.Write(XORData[1], Length(XORData));
  74.           finally
  75.           end;
  76.         finally
  77.          fOut.free;
  78.         end;
  79.       finally
  80.         fIn.Free;
  81.       end;
  82.     end;
  83.   end;
  84.   Label2.Caption:= ' Finished.';
  85. end;
  86.                  
  87.  
« Last Edit: May 22, 2018, 03:10:53 pm by Gizmo »

 

TinyPortal © 2005-2018