XEBI — простой алгоритм шифрование Unicode строк на Delphi

Данный алгоритм основан на шифрование строк с помощью 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.
XEBI

Скачать с Яндекс.Диск