# Native Code > برنامه نویسی در Delphi > مقالات مرتبط با Delphi/Win32 > مقاله: رمز کردن اطلاعات

## lord_viper

امروزه یکی از مهمترین بخشهای امنیت در کامپیوتر مقوله رمزنگاری داده ها میباشد رمزنگاری باعث اطمینان از در امان ماندن محتوی اسناد در مقابل عوامل خارجی میباشد.روشهای مختلفی برای رمز نگاری وجود 
1.کد کردن اطلاعات: کدینگ یا در هم ریزی دادها روشی برای غیر قابل خوانا کردن فایلها و نوشته ها میباشد که معمولا از 1 الگوریتم تشکیل میشود مانند rot13
2.انکریپت کردن:اطلاعات با استفاده از حداقل یک کلید و الگوریتمهای خاصی تغییر داده میشوند که همیشه از 2 الگوریتم در ان استفاده میشود یکی برای انکریپت و دیگری برای دیکریپت  مانند 3des
3.هش کردن:در این روش اطلاعات با استفاده از الگوریتمهای خاصی تبدیل یه یک چکیده با طول خاص میشوند  مثلا 128 یا 256 بایت کمتر یا بیشتر(بسته به نوع الگوریتم) مانند md5
 خب ما در چه مواقعی از این الگوریتمها استفاده میکنیم

1.وقتی که می خواهید مطمئن باشید که ایمیلی را که می‌فرستید تنها گیرنده‌ی مورد نظر می‌تواند بخواند؛ و در بين راه ارسال یا حتی پس از دریافت برای کس دیگری قابل خواندن نباشد.
2.وقتی می‌خواهید اطلاعات خاصی را (نوشته، عکس و یا ویدئو) تنها برای خود یا فرد خاصی قابل دسترسی کنید.
3.وقتی می‌خواهید یک گروه درست کنید و از شنود افراد غیر مجاز در امان باشید. در واقع، ابداع‌کننده‌ی اصلی این روش، یعنی فیل زیمرمن، از فعالان ضدهسته‌ای در ایالات متحد بود که برای تدارک دیدن تظاهرات و کارشکنی در انتقال مواد هسته‌ای نیاز به حذف شنود FBI داشت.
3.وقتی نگران هستید که اطلاعات و محتوای ایمیل‌تان توسط شرکت‌های فراهم‌آورنده‌ی ایمیل مجانی برای تهیه‌ی یک پروفایل تجاری از شما و هدف‌گیری تبلیغاتی‌تان - و نیت‌های شوم دیگراستفاده شود.
4.وقتی می‌خواهید مطمئن شوید نویسنده یا تولید کننده‌ی یک مطلب حتماً همان کسی است که ادعا می‌کند.
5. وقتی روزانه تعداد زیادی ایمیل و اسپم دریافت می‌کنید، می‌توانید بگویید تنها به ایمیل‌هایی جواب می‌دهید که رمز شده باشند (این کاری است که مخترع WWW، یعنی Sir Tim Berners Lee و تعدادی دیگر از همکاران‌اش در Cern انجام داده‌اند). سرورهای فرستنده‌ی اسپم به دلیلِ هزینه‌ی محاسباتی رمز نگاری نمی‌توانند ایمیل رمز شده بفرستند.

همانگونه که در بالا گفته شد روشهای مختلفی برای رمز نگاری اطلاعات وجود دارد که یکی از ساده ترین روشها کد کردن اطلاعات میباشد دارد مثلا کلمه hello را 1 حرف به جلو شیفت میدهم در این حالت حرف o از انتها به ابتدای کلمه منتقل خواهد شد و به صورت زیر در خواهد آمئ elloh یا مثلا هر حرفی با حرف بعد از خود جایگزین شود در این حالت کلمه hello به صورت ifmmp در خواهد آمد.الگوریتمهای مختلفی برای این کار وجود دارد که عمومی ترین آنها 
Xor – rot13 – Base64–  میباشد که در این مقاله به پیاده سازی اینها میپردازیم
XOR
 در این روش متن مورد نظر را با یک مقدار XOR میکنیم همانطور که میدانید XOR یک عملگر منطقی میباشد 



درجدول فوق شرط درستی در حالتی است که حتما یکی از المانها غلط False یا 0   باشد
خب حالا به پیاده سازی الگوریتم میپردازیم   خب یک پروژه جدید ایجاد و یک Label-Edit-button روی فورم قرار میدهیم و در رویداد Onclick دکمه کد زیر را بنویسید

procedure TForm1.btn_xorClick(Sender: TObject);
var
ch,ci:Char;
str,val:string;
begin
str:=edit1.Text;
for ch in str do
begin
ci:=chr(Ord(ch)xor 31);
val:=val+ci;
end;
label1.Caption:=val;
end;


تابع ord مقدار یک حرف(کاراکتر) را به مقدار معادل عددی ان در استاندارد ASCII تبدیل میکند و تابع chr هم یک مقدار عددی را به مقدار کاراکتر معادل ان در استاندارد ASCII تبدیل میکند ما در این الگوریتم مقدار هر کاراکتر را با عدد 31 عمل xor انجام میدهیم در این حالت مقدار رمز شده کلمه hello به صورت wzssp خواهد بود




ROT13
همانطور که میدانید زبان انگلیسی دارای 26 حرف میباشد13=2/26 میباشد ROT هم به معنی rotate یا گردش میباشد در این الگوریتم حروف بزرگ و کوچک به 2 دسته 13 تایی تقسیم میشوند از a-m  A-M و n-z N-Z تقسیم میشوند اگر مقدار عددی ASCII یک حرف در گروه اول باشد مقدار آن با 13 جمع میشود اگر مقدار عددی ASCII یک حرف در گروه دوم باشد مقدار ان از 13 کم میشود به مثال زیر توجه کنید

function rot_encode(val: string; num: Integer): string;
var
  ch: Char;
  i: Integer;
  str: string;
begin
  str := '';
  for ch in val do
  begin
  if (ch in['a'..'m'])or (ch in['A'..'M']) then


اگر مقدار کاراکتر ch در گروه اول a-m ,A-Z باشد مقدار آن با 13 جمع میشود

  i:=ord(ch)+13
  else
  if(ch in['n'..'z'])or(ch in['N'..'Z'])then

اگر مقدار کاراکتر ch در گروه اول n-z ,N-Z باشد مقدار آن با 13 جمع میشود

  i:=ord(ch)-13
  else
  i:=Ord(ch);
  str:=str+chr(i);
  end;
  result := str;
end;
روش استفاده
edit2.Text := rot_encode(edti1.Text);




Base64
این کدینگ از معروفترین کدینگها میباشد که کاربرد زیادی نیز دارد که از مصارف اون انتقال وصله های ایمیلهاست به دلیل اینکه در پروتکل MIME باید از کاراکترهای اسکی استفاده نمود لذا از این روش کدینگ استفاده می شود(بعضی از کاراکتر های غیر اسکی در این پروتکل معنی خاصی دارند) .برای اطلاعات بیشتر RFC های مربوط به MIME را بخوانید و در بعضی برنامه های تحت وب برای ساختن ادرس صفحات وب ازش استفاده میشود طراحی و پیاده سازی این الگوریتم بسیار ساده میباشد کدی که در این روش تولید میشود طولش 33% از مقدار اولیه بیشترخواهد بود
پیاده سازی الگوریتم
ما در base64 دارای64 سمبل میباشیم که از0 تا63 شماره گزاری میشوند
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx  yz0123456789+/
 این الگوریتم بر روی بیتها و بایتها اعمال میشود به این صورت که هر متنی از مجموعه حروف تشکیل میشود و در حالت عمومی حر حرف یا هر کاراکتر 1 بایت میباشد و هر بایت 8 بیت میباشد ولی کاراکترهای استفاده شده در این الگوریتم 6 بیتی میباشد و این رمز نهفته در این الگوریتم میباشد ابتدا حروف یک عبارت را تبدیل به بایتها و بیتهای متناظر آن میکنیم 
در این مثال فرض کنید ما کلمه Man را می خواهید به Bace64 انکد کنید
Man از 3 حرفM,a,n تشکیل شده است که مقدار asciiبرابر شماره 77,97,110 در مبنای 10 میباشد حال این اعداد را به مبنای 2 میبریم توجه داشته باشید که حتما در تبدیل باید طول هر کدام 8 بایت شود برای این کار بعد از تبدیل به مبنای 2 انقدر به اول ان 0 اضافه کنید تا طول ان به 8 برسد .اعداد فوق در مبنی 2 بصورت 01001101, 01100001, 01101110 است حال این بیتها را کنار هم قرار میدهیم تا رشتهای از بیتها بوجود اید
0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
با توجه به اینکه 6^2 سمبل داریم پس هر کاراکتر در پایه64, 6 بیتی می باشد در صورتی که در اسکی کاراکتر ها 8 بیتی هستند
در base64 کاراکترها 6 بیتی میباشند حالا ما رشته را 6 بیت 6 بیت جدا میکنیم و به مبنای 10 میبریم که میشود
19 22 5 46
حالا مقدار این اعداد را از جدول base64 میخوانیم که میشود
T W F u
حال اگر تعداد کاراکترها 5 تا باشد طول رشته ما 40 میشود که در این مبنا 6 کاراکتر میشود و برای کاراکتر بعدی 2 بیت کم می اید در اینجا ما 4 بیت را به مبنای 10 برده و مقدار را ازجدول میخوانیم و به ازای هر 2 بیت که داریم یک= قرار میدهیم مثلا sazan در base64 بصورت c2F6YW4= میشود . برای دیکود کردن هم کافی است همین روند را از انتها به ابتدا دنبال کنید. البته این الگوریتم در خود زبان دلفی در یونیت Soap.EncdDecd  قرار دارد و به سادگی با uses کردن آن و استفاده از توابع زیر این کار را انجام دهید

EncodeString(val:string):string;
DecodeString(val:string):string
مثال:
showmessage(EncodeString('lord_viper'));
مقدار کد شده عبارت lord_viper برابر با  bG9yZF92aXBlcg== خواهد بود و برای دیکود به صورت زیر عمل کنید
showmessage(DecodeString('bG9yZF92aXBlcg=='));

این هم چند نمونه کد به زبان دلفی

function Decode(const S: AnsiString): AnsiString; 
const 
  Map: array[Char] of Byte = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, 
    54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 
    3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
    20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 
    31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 
    46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0); 
var 
  I: LongInt; 
begin 
  case Length(S) of 
    2:  
      begin 
        I := Map[S[1]] + (Map[S[2]] shl 6); 
        SetLength(Result, 1); 
        Move(I, Result[1], Length(Result)) 
      end; 
    3:  
      begin 
        I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12); 
        SetLength(Result, 2); 
        Move(I, Result[1], Length(Result)) 
      end; 
    4:  
      begin 
        I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) + 
          (Map[S[4]] shl 18); 
        SetLength(Result, 3); 
        Move(I, Result[1], Length(Result)) 
      end 
  end 
end; 

function Encode(const S: AnsiString): AnsiString; 
const 
  Map: array[0..63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 
    'abcdefghijklmnopqrstuvwxyz0123456789+/'; 
var 
  I: LongInt; 
begin 
  I := 0; 
  Move(S[1], I, Length(S)); 
  case Length(S) of 
    1: 
      Result := Map[I mod 64] + Map[(I shr 6) mod 64]; 
    2: 
      Result := Map[I mod 64] + Map[(I shr 6) mod 64] + 
        Map[(I shr 12) mod 64]; 
    3: 
      Result := Map[I mod 64] + Map[(I shr 6) mod 64] + 
        Map[(I shr 12) mod 64] + Map[(I shr 18) mod 64] 
  end 
end;

مثالی دیگر


function EncodeBase64 (Value: String): String;
 const
  b64alphabet: PChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw  xyz0123456789 + /';
   pad: PChar = '====';

   function EncodeChunk (const Chunk: String): String;
   var
     W: LongWord;
     i, n: Byte;
   begin
     n: = Length (Chunk); W: = 0;
     for i: = 0 to n - 1 do
       W: = W + Ord (Chunk [i + 1]) shl ((2 - i) * 8);
     Result: = b64alphabet [(W shr 18) and $ 3f] +
               b64alphabet [(W shr 12) and $ 3f] +
               b64alphabet [(W shr 06) and $ 3f] +
               b64alphabet [(W shr 00) and $ 3f];
     if n <> 3 then
       Result: = Copy (Result, 0, n + 1) + Copy (pad, 0, 3 - n); / / add padding when out len isn 't 24 bits 
    end; 

  begin 
    Result: = ''; 
    while Length (Value)> 0 do 
    begin 
      Result: = Result + EncodeChunk (Copy (Value, 0, 3)); 
      Delete (Value, 1, 3); 
    end; 
  end; 


  function DecodeBase64 (Value: String): String; 
  const b64alphabet: PChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw  xyz0123456789 + /'; 
    function DecodeChunk (const Chunk: String): String; 
    var 
      W: LongWord; 
      i: Byte; 
    begin 
      W: = 0; Result: = ''; 
      for i: = 1 to 4 do 
        if Pos (Chunk [i], b64alphabet) <> 0 then 
          W: = W + Word ((Pos (Chunk [i], b64alphabet) - 1)) shl ((4 - i) * 6); 
      for i: = 1 to 3 do 
        Result: = Result + Chr (W shr ((3 - i) * 8) and $ ff); 
    end; 
  begin 
    Result: = '';
   if Length (Value) mod 4 <> 0 then Exit;
   while Length (Value)> 0 do
   begin
     Result: = Result + DecodeChunk (Copy (Value, 0, 4));
     Delete (Value, 1, 4);
   end;
 end;

----------

