Xorowanie strumieni
Misiekd
Klasa nie jest mojego pomysłu, jej implementację znalazłem gdzieś na sieci.
Jest to klasa, która w prosty sposób koduje strumień przy pomocy XORowania.
unit XorStreamCipher;
interface
uses
SysUtils, Classes;
type
TXorStreamCipher = class
private
FPassStream: TStream;
FInStream: TStream;
FOutStream: TStream;
procedure SetInStream(const Value: TStream);
procedure SetOutStream(const Value: TStream);
procedure SetPassStream(const Value: TStream);
public
procedure Process;
property InStream: TStream Read FInStream Write SetInStream;
property OutStream: TStream Read FOutStream Write SetOutStream;
property PassStream: TStream Read FPassStream Write SetPassStream;
end;
implementation
{ TXorStreamCipher }
procedure TXorStreamCipher.Process;
function StreamsAssigned: boolean;
begin
Result := Assigned(FInStream) and Assigned(FOutStream) and Assigned(FPassStream);
end;
function StreamsDifferent: boolean;
begin
Result := (FInStream <> FOutStream) and (FOutStream <> FPassStream) and (FPassStream <> FInStream);
end;
procedure RewindStream(const AStream: TStream);
begin
AStream.Seek(0, soFromBeginning);
end;
function GetByte(const AStream: TStream): byte;
begin
AStream.Read(Result, SizeOf(byte))
end;
procedure PutByte(const AStream: TStream; const AByte: byte);
begin
AStream.Write(AByte, SizeOf(byte));
end;
function Eos(const AStream: TStream): boolean;
begin
with AStream do
Result := (Position = {Pred}(Size));
end;
begin
if StreamsAssigned and StreamsDifferent then
begin
RewindStream(FInStream);
RewindStream(FOutStream);
RewindStream(FPassStream);
while not Eos(FInStream) do
begin
PutByte(FOutStream, GetByte(FInStream) xor GetByte(FPassStream));
if Eos(FPassStream) then
RewindStream(FPassStream);
end;
end
else
raise Exception.Create('You must assign all 3 streams to properties.');
end;
procedure TXorStreamCipher.SetInStream(const Value: TStream);
begin
FInStream := Value;
end;
procedure TXorStreamCipher.SetOutStream(const Value: TStream);
begin
FOutStream := Value;
end;
procedure TXorStreamCipher.SetPassStream(const Value: TStream);
begin
FPassStream := Value;
end;
end.
przykład użycia
var
InStream, OutStream: TFileStream;
PassStream: TMemoryStream;
XorStream: TXorStreamCipher;
pass: string;
begin
InStream := TFileStream.Create('ścieżka i nazwa pliku in', fmOpenRead or fmShareExclusive);
OutStream := TFileStream.Create('ścieżka i nazwa pliku out', fmCreate);
PassStream := TMemmoryStream.Create;
XorStream := TXorStreamCipher.Create;
try
PassStream.Write(pass, Length(pass)); //można też np. wczytać z pliku
XorStream.PassStream := PassStream;
XorStream.InStream := InStream;
XorStream.OutStream := OutStream;
XorStream.Process;
finally
FreeAndNil(InStream);
FreeAndNil(OutStream);
FreeAndNil(PassStream);
FreeAndNil(XorStream);
end;
end;
Deszyfrowanie to po prostu zaszyfrowanie pliku raz jeszcze
SOA#1
Fajnie, tyle że zamienia wszystkie znaki na spacjo-podobne :> a tu chyba o to nie chodzi