Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Шифрование и дешифрование текстов по принципу S-Coder со скрытым ключом

01.01.2007
{ **** UBPFD *********** by kladovka.net.ru ****
>> Шифрование и дешифрование текстов по принципу S-Coder со скрытым ключом
 
После прменения выполнения функции Encrypt с входным исходным 
текстом, результат будет иметь символы в диапазоне от 
0 - 255 в ASCII таблице, следовательно если вам надо сохранить 
где либо шифровку, то лучше преобразовать в числовой вид - 
16разрядный hex из ASCII таблицы (функция Write)
 
Зависимости: Windows, SysUtils
Автор:       Yuri Btr, btr1978@rambler.ru, ICQ:125988632, Керчь
Copyright:   EFD Systems http://www.mindspring.com/~efd
Дата:        23 мая 2002 г.
********************************************** }
 
procedure EnCipher(var Source:AnsiString);
 
  {Low order, 7-bit ASCII (char. 32-127) encryption designed for database use.
   Control and high order (8 bit) characters are passed through unchanged.
 
   Uses a hybrid method...random table substitution with bit-mangled output.
   No passwords to worry with (the built-in table is the password). Not industrial
   strength but enough to deter the casual hacker or snoop. Even repeating char.
   sequences have little discernable pattern once encrypted.
 
   NOTE: When displaying encrypted strings, remember that some characters
         within the output range are interpreted by VCL components; for
         example, '&'.}
 
  asm
    Push ESI //Save the good stuff
    Push EDI
 
    Or EAX,EAX
    Jz @Done
    Push EAX
    Call UniqueString
    Pop EAX
    Mov ESI,[EAX] //String address into ESI
    Or ESI,ESI
    Jz @Done
    Mov ECX,[ESI-4] //String Length into ECX
    Jecxz @Done //Abort on null string
    Mov EDX,ECX //initialize EDX with length
    Lea EDI,@ECTbl //Table address into EDI
    Cld //make sure we go forward
@L1:
    Xor EAX,EAX
    Lodsb //Load a byte from string
    Sub AX,32 //Adjust to zero base
    Js @Next //Ignore if control char.
    Cmp AX,95
    Jg @Next //Ignore if high order char.
    Mov AL,[EDI+EAX] //get the table value
    Test CX,3 //screw it up some
    Jz @L2
    Rol EDX,3
@L2:
    And DL,31
    Xor AL,DL
    Add EDX,ECX
    Add EDX,EAX
    Add AL,32 //adjust to output range
    Mov [ESI-1],AL //write it back into string
@Next:
    Dec ECX
    Jnz @L1
// Loop @L1 //do it again if necessary
 
@Done:
    Pop EDI
    Pop ESI
 
    Jmp @Exit
// Ret //this does not work with Delphi 3 - EFD 971022
 
@ECTbl: //The encipher table
    DB 75,85,86,92,93,95,74,76,84,87,91,94
    DB 63,73,77,83,88,90,62,64,72,78,82,89
    DB 51,61,65,71,79,81,50,52,60,66,70,80
    DB 39,49,53,59,67,69,38,40,48,54,58,68
    DB 27,37,41,47,55,57,26,28,36,42,46,56
    DB 15,25,29,35,43,45,14,16,24,30,34,44
    DB 06,13,17,23,31,33,05,07,12,18,22,32
    DB 01,04,08,11,19,21,00,02,03,09,10,20
@Exit:
 
  end;
 
 
procedure DeCipher(var Source:AnsiString);
 
  {Decrypts a string previously encrypted with EnCipher.}
 
  asm
    Push ESI //Save the good stuff
    Push EDI
    Push EBX
 
    Or EAX,EAX
    Jz @Done
    Push EAX
    Call UniqueString
    Pop EAX
    Mov ESI,[EAX] //String address into ESI
    Or ESI,ESI
    Jz @Done
    Mov ECX,[ESI-4] //String Length into ECX
    Jecxz @Done //Abort on null string
    Mov EDX,ECX //Initialize EDX with length
    Lea EDI,@DCTbl //Table address into EDI
    Cld //make sure we go forward
@L1:
    Xor EAX,EAX
    Lodsb //Load a byte from string
    Sub AX,32 //Adjust to zero base
    Js @Next //Ignore if control char.
    Cmp AX,95
    Jg @Next //Ignore if high order char.
    Mov EBX,EAX //save to accumulate below
    Test CX,3 //unscrew it
    Jz @L2
    Rol EDX,3
@L2:
    And DL,31
    Xor AL,DL
    Add EDX,ECX
    Add EDX,EBX
    Mov AL,[EDI+EAX] //get the table value
    Add AL,32 //adjust to output range
    Mov [ESI-1],AL //store it back in string
@Next:
    Dec ECX
    Jnz @L1
// Loop @L1 //do it again if necessary
 
@Done:
    Pop EBX
    Pop EDI
    Pop ESI
 
    Jmp @Exit
// Ret Does not work with Delphi3 - EFD 971022
 
@DCTbl: //The decryption table
    DB 90,84,91,92,85,78,72,79,86,93,94,87
    DB 80,73,66,60,67,74,81,88,95,89,82,75
    DB 68,61,54,48,55,62,69,76,83,77,70,63
    DB 56,49,42,36,43,50,57,64,71,65,58,51
    DB 44,37,30,24,31,38,45,52,59,53,46,39
    DB 32,25,18,12,19,26,33,40,47,41,34,27
    DB 20,13,06,00,07,14,21,28,35,29,22,15
    DB 08,01,02,09,16,23,17,10,03,04,11,05
@Exit:
  end;
 
 
procedure Crypt(var Source:Ansistring;const Key:AnsiString);
 
  {Encrypt AND decrypt strings using an enhanced XOR technique similar to
   S-Coder (DDJ, Jan. 1990). To decrypt, simply re-apply the procedure
   using the same password key. This algorithm is reasonably secure on
   it's own; however,there are steps you can take to make it even more
   secure.
 
         1) Use a long key that is not easily guessed.
         2) Double or triple encrypt the string using different keys.
            To decrypt, re-apply the passwords in reverse order.
         3) Use EnCipher before using Crypt. To decrypt, re-apply Crypt
            first then use DeCipher.
         4) Some unique combination of the above
 
   NOTE: The resultant string may contain any character, 0..255.}
 
 
  asm
    Push ESI //Save the good stuff
    Push EDI
    Push EBX
 
    Or EAX,EAX
    Jz @Done
    Push EAX
    Push EDX
    Call UniqueString
    Pop EDX
    Pop EAX
    Mov EDI,[EAX] //String address into EDI
    Or EDI,EDI
    Jz @Done
    Mov ECX,[EDI-4] //String Length into ECX
    Jecxz @Done //Abort on null string
    Mov ESI,EDX //Key address into ESI
    Or ESI,ESI
    Jz @Done
    Mov EDX,[ESI-4] //Key Length into EDX
    Dec EDX //make zero based
    Js @Done //abort if zero key length
    Mov EBX,EDX //use EBX for rotation offset
    Mov AH,DL //seed with key length
    Cld //make sure we go forward
@L1:
    Test AH,8 //build stream char.
    Jnz @L3
    Xor AH,1
@L3:
    Not AH
    Ror AH,1
    Mov AL,[ESI+EBX] //Get next char. from Key
    Xor AL,AH //XOR key with stream to make pseudo-key
    Xor AL,[EDI] //XOR pseudo-key with Source
    Stosb //store it back
    Dec EBX //less than zero ?
    Jns @L2 //no, then skip
    Mov EBX,EDX //re-initialize Key offset
@L2:
    Dec ECX
    Jnz @L1
@Done:
    Pop EBX //restore the world
    Pop EDI
    Pop ESI
  end;
 
 function Encrypt(text:Ansistring):Ansistring;
//Это прсто интерфейс функций EnCipher и Crypt для шифрования строки текста
begin
 {шифруем текст}
 EnCipher(Text);
 {зашифровываем ключом в Edit1}
 Crypt(Text,Form1.Edit1.Text);
 Result:=Text;
end;
 
 
function Decrypt(text:Ansistring):Ansistring;
//Это прсто интерфейс функций EnCipher и Crypt для дешифрования строки текста begin
begin
 {расшифровываем ключом в Edit1}
 Crypt(Text,Form1.Edit1.Text);
 {расшифровываем результат}
 DeCipher(Text);
 Result:=Text;
end;
 
 
function Write(text:Ansistring):Ansistring;
var
 i:integer;
begin
 Result:='';
 For i:=1 to Length(text)
  do
   {получаем hex код из текста}
   Result:=Result+InttoHex(ord(text[i]),2);
end;
 
function Read(text:Ansistring):Ansistring;
var
 i:integer;
begin
 Result:='';
 For I:=1 to Length(text)
  do
   if odd(i)
    then
     {получаем текст из hex кода} 
     Result:=Result+Chr(StrtoInt('$'+text[i]+text[i+1]));
end; 

Пример использования:

функции вставляем после Implementation

и после {$R *.dfm}

В программе пишем просто:

procedure TForm1.Button1Click(Sender: TObject);
begin
 {Задайте здесь ваш секретный ключ}
 Edit1.text:='My special hidden key'; 
 {Шифруем и преобразовываем тест в Memo1 и заносим результат в Memo2}
 Memo2.text:=Write(Encrypt(Memo1.text));
 {Дешифруем и преобразовываем тест в Memo2 и заносим результат в Memo3}
 Memo3.text:=Decrypt(Read(Memo2.text));));
end;