Данный алгоритм основан на шифрование строк с помощью XOR. Ранее в своих программах на Delphi 7 я использовал простейший алгоритм, основанный на XOR исходного текста и пароля (ord(текст[0]) xor ord(пароль[0])). Но как писал в предыдущий статье, посвященной конвертации строки в HEX и обратно, с переходом Delphi на кодировку Unicode, возникли трудности при использование данного метода (в принципе, трудностей нет, можно просто вместо типа String использовать AnsiString, так как по умолчанию сейчас в Delphi тип String является UnicodeString, то есть 1 символ имеет минимум размер 2 байта), но я решил написать и, в последующем, использовать более универсальный метод шифрования, названный XEBI.
Исходный код алгоритма шифрования строк XEBI:
function xebi(const text, passwd:string):string;
const
szBuffer = SizeOf(LongWord);
szByteBuffer = SizeOf(Byte);
var
HashPasswd, buffer, i, byteBuffer: LongWord;
StreamOut, StreamIn: TStringStream;
function Murmur2(const S: String; const Seed: LongWord=$9747b28c): LongWord;
var
hash, len, k: LongWord;
StrAsBytes:TBytes;
data: Integer;
const
m = $5bd1e995;
r = 24;
begin
StrAsBytes:=TEncoding.UTF8.GetBytes(S);
len:=Length(StrAsBytes);
hash:=seed xor len;
data:=0;
while(len >= 4) do
begin
k := PLongWord(@StrAsBytes[data])^;
k := k*m;
k := k xor (k shr r);
k := k*m;
hash := hash*m;
hash := hash xor k;
inc(data,4);
dec(len,4);
end;
Assert(len <= 3);
if len = 3 then hash := hash xor (LongWord(StrAsBytes[data+2]) shl 16);
if len >= 2 then hash := hash xor (LongWord(StrAsBytes[data+1]) shl 8);
if len >= 1 then
begin
hash := hash xor (LongWord(StrAsBytes[data])); hash := hash * m;
end;
hash := hash xor (hash shr 13);
hash := hash * m;
hash := hash xor (hash shr 15);
Result := hash;
end;
begin
StreamIn:=TStringStream.Create(text);
StreamOut:=TStringStream.Create('');
try
StreamIn.Position:=0;
StreamOut.Position:=0;
HashPasswd:=Murmur2(passwd);
while (StreamIn.Position<StreamIn.Size) and ((StreamIn.Size-StreamIn.Position)>=szBuffer) do
begin
StreamIn.ReadBuffer(buffer, szBuffer);
buffer := buffer xor HashPasswd;
buffer := buffer xor $E0F;
StreamOut.WriteBuffer(buffer, szBuffer);
end;
if (StreamIn.Size-StreamIn.Position)>=1 then
for i:=StreamIn.Position to StreamIn.Size-1 do
begin
StreamIn.ReadBuffer(byteBuffer, szByteBuffer);
byteBuffer:=byteBuffer xor $F;
StreamOut.WriteBuffer(byteBuffer, szByteBuffer);
end;
StreamOut.Position:=0;
Result:=StreamOut.ReadString(StreamOut.Size);
finally
StreamOut.Free;
StreamIn.Free;
end;
end;
Использование:
enstr:=xebi(source, password);
Для расшифровки передаем функции ранее зашифрованный текст (вместо source) и пароль.
В своем алгоритме шифрования текста я использовал функцию хеширования Murmur2A, отличающейся великолепной скоростью создания хешей и высокой устойчивостью к коллизиям.
Для хранения в текстовом файле зашифрованного текса, рекомендую использовать конвертацию шифрованного текста в HEX.
Ниже, Вы сможете скачать пример программы шифрования текста с исходником, использующая функцию шифрования текста XEBI.