MiTec/Common/MiTeC_SimpleCrypt.pas
2024-07-06 22:30:25 +02:00

183 lines
4.6 KiB
ObjectPascal

{*******************************************************}
{ MiTeC Simple Crypt }
{ Simple string XOR and ROT encryption }
{ }
{ Copyright (c) 2014-2021 Michal Mutl }
{ }
{*******************************************************}
{$I Compilers.inc}
unit MiTeC_SimpleCrypt;
interface
uses {$IFDEF RAD9PLUS}
WinAPI.Windows, System.SysUtils
{$ELSE}
Windows, SysUtils
{$ENDIF}
;
const
binC1 = 51265;
binC2 = 21424;
dbC1 = 51855;
dbC2 = 21729;
cKey1 = 210;
cKey2 = 211;
cKey3 = 100;
function EncryptString(const s: string; Key: Integer = cKey1; AC1: Integer = dbC1; AC2: Integer = dbC2): string;
function DecryptString(const s: string; Key: Integer = cKey1; AC1: Integer = dbC1; AC2: Integer = dbC2): string;
function EncryptStringA(const S: AnsiString; Key,AC1,AC2: LongInt): AnsiString;
function DecryptStringA(const S: AnsiString; Key,AC1,AC2: LongInt): AnsiString;
function EncryptStringW(const S: WideString; Key,AC1,AC2: LongInt): WideString;
function DecryptStringW(const S: WideString; Key,AC1,AC2: LongInt): WideString;
function RotateBy(AStr: String; const ARotate: Integer = 47): string;
implementation
{$IFNDEF RAD7PLUS}
function CharInSet(C: Char; const CharSet: TSysCharSet): Boolean;
begin
Result := C in CharSet;
end;
{$ENDIF}
function EncryptStringA(const S: AnsiString; Key,AC1,AC2: LongInt): AnsiString;
var
i,l: byte;
begin
Result:='';
for i:=1 to Length(S) do begin
l:=byte(S[i]) xor (Key and $07);
if l = 35 then
l:=127;
Result:=Result+ansichar(l);
Key:=(byte(Result[i])+Key)*AC1+AC2;
end;
end;
function DecryptStringA(const S: AnsiString; Key,AC1,AC2: LongInt): AnsiString;
var
i,l: byte;
begin
Result:='';
for i:=1 to Length(S) do begin
l:=byte(S[i]);
if l=127 then
l:=35;
Result:=Result+ansichar(l xor (Key and $07));
Key:=(byte(S[i])+Key)*AC1+AC2;
end;
end;
function EncryptStringW(const S: WideString; Key,AC1,AC2: LongInt): WideString;
var
i,l: word;
begin
Result:='';
for i:= 1 to Length(s) do begin
l:=word(S[i]) xor (Key and $07);
if l = 35 then
l:=127;
Result:=Result+widechar(l);
Key:=(word(Result[i])+Key)*AC1+AC2;
end;
end;
function DecryptStringW(const S: WideString; Key,AC1,AC2: LongInt): WideString;
var
i,l: word;
begin
Result:='';
for i:=1 to Length(s) do begin
l:=word(s[i]);
if l=127 then
l:=35;
Result:=Result+widechar(l xor (Key and $07));
Key:=(word(S[i])+Key)*AC1+AC2;
end;
end;
function EncryptString;
begin
if Length(s)>256 then
raise Exception.Create('Cannot encrypt string longer than 256 chars.');
{$IFDEF UNICODE}
Result:=EncryptStringW(S,Key,AC1,AC2);
{$ELSE}
Result:=EncryptStringA(S,Key,AC1,AC2);
{$ENDIF}
end;
function DecryptString;
begin
{$IFDEF UNICODE}
Result:=DecryptStringW(S,Key,AC1,AC2);
{$ELSE}
Result:=DecryptStringA(S,Key,AC1,AC2);
{$ENDIF}
end;
function RotateBy(AStr: String; const ARotate: Integer = 47): String;
function RotateChar(AChr: Char; ARotate: Integer): Char;
var
iStart, iRotate: Integer;
begin
iRotate:=0;
iStart := 0;
case ARotate of
5: if CharInSet(AChr,['0'..'9']) then begin
iStart := 48; // '0'
iRotate := 5;
end;
13: if CharInSet(AChr,['A'..'Z']) then begin
iStart := 65; // 'A'
iRotate := 13;
end
else if CharInSet(AChr,['a'..'z']) then begin
iStart := 97; // 'a'
iRotate := 13;
end;
18: if CharInSet(AChr,['0'..'9']) then begin
iStart := 48; // '0'
iRotate := 5;
end
else if CharInSet(AChr,['A'..'Z']) then begin
iStart := 65; // 'A'
iRotate := 13;
end
else if CharInSet(AChr,['a'..'z']) then begin
iStart := 97; // 'a'
iRotate := 13;
end;
47: if CharInSet(AChr,['!'..'~']) then begin
iStart := 33; // '!'
iRotate := 47;
end
end;
if iStart>0 then
Result := Chr(iStart + ((Ord(AChr) - iStart + iRotate) mod (iRotate * 2)))
else
Result := AChr;
end;
var
I: Integer;
begin
Result := '';
for I := 1 to Length(AStr) do
Result := Result + RotateChar(AStr[I], ARotate);
end;
end.