lord_viper
مدیر کل انجمن
ارسالها: 3,949
موضوعها: 352
تاریخ عضویت: بهمن ۱۳۸۴
تشکرها : 5193
( 9875 تشکر در 2650 ارسال )
|
مقاله: الگوریتم base64
الگوریتم base64
یکی از مباحث مهم در امنیت دادها استفاده از روشهای کدینگ میباشد کدینگ چیست؟ کدینگ یا در هم ریزی دادها روشی برای غیر قابل خوانا کردن فایلها و نوشته ها میباشد که معمولا از 1 جفت الگوریتم تشکیل میشود یکی برای encode کردن و دیگری برای decode کردن مثلا در یک حلقه for تک تک کاراکترهاتونو با 256 xor کرده و جواب رو مینویسید این میشه بخش encode و هر وقت احتیاج بهش داشتین با الگوریتم دوم که قرینه الگوریتم اول ما هست اونو به حالت اول برمیگردونیم البته استفاده از xor یه مثال ساده بوده و برای مسائل مهم کسی از این روش استفاده نمیکنه یکی از الگوریتمهای معروف در زمینه کد کردن الگوریتم base64 هست که مصارف اون انتقال وصله های ایمیلهاست به دلیل اینکه در پروتکل MIME باید از کاراکترهای اسکی استفاده نمود لذا از این روش کدینگ استفاده می شود(بعضی از کاراکتر های غیر اسکی در این پروتکل معنی خاصی دارند) .برای اطلاعات بیشتر RFC های مربوط به MIME را بخوانید
و در بعضی برنامه های تحت وب برای ساختن ادرس صفحات وب ازش استفاده میشه
طراحی و پیاده سازی این الگوریتم بسیار ساده و جالبه کدی که در این روش تولید میشه طولش 33% از مقدار اولیه بیشتره
حالا پیاده سازی الگوریتم
ما در base64 دارای64 سمبل میباشیم که از0 تا63 شماره گزاری میشوند
کد: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
کاراکترهایی که ما بطور معمول از انها استفاده میکنیم 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= میشود
موفق باشید
این هم چند نمونه کد به زبان دلفی
کد: 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;
کد: type TAByte = array [0..maxInt-1] of byte;
type TPAByte = ^TAByte;
function Encode(data:string) : string; overload;
const b64 : array [0..63] of char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var ic,len : integer;
pi, po : TPAByte;
c1 : dword;
begin
len:=length(data);
if len > 0 then begin
SetLength(result, ((len + 2) div 3) * 4);
pi := pointer(data);
po := pointer(result);
for ic := 1 to len div 3 do begin
c1 := pi^[0] shl 16 + pi^[1] shl 8 + pi^[2];
po^[0] := byte(b64[(c1 shr 18) and $3f]);
po^[1] := byte(b64[(c1 shr 12) and $3f]);
po^[2] := byte(b64[(c1 shr 6) and $3f]);
po^[3] := byte(b64[(c1 ) and $3f]);
inc(dword(po), 4);
inc(dword(pi), 3);
end;
case len mod 3 of
1 : begin
c1 := pi^[0] shl 16;
po^[0] := byte(b64[(c1 shr 18) and $3f]);
po^[1] := byte(b64[(c1 shr 12) and $3f]);
po^[2] := byte('=');
po^[3] := byte('=');
end;
2 : begin
c1 := pi^[0] shl 16 + pi^[1] shl 8;
po^[0] := byte(b64[(c1 shr 18) and $3f]);
po^[1] := byte(b64[(c1 shr 12) and $3f]);
po^[2] := byte(b64[(c1 shr 6) and $3f]);
po^[3] := byte('=');
end;
end;
end else
result := '';
end;
function Decode(data:string) : string; overload;
var i1,i2,len : integer;
pi, po : TPAByte;
ch1 : char;
c1 : dword;
begin
len:=length(data);
if (len > 0) and (len mod 4 = 0) then begin
len := len shr 2;
SetLength(result, len * 3);
pi := pointer(data);
po := pointer(result);
for i1 := 1 to len do begin
c1 := 0;
i2 := 0;
while true do begin
ch1 := char(pi^[i2]);
case ch1 of
'A'..'Z' : c1 := c1 or (dword(ch1) - byte('A') );
'a'..'z' : c1 := c1 or (dword(ch1) - byte('a') + 26);
'0'..'9' : c1 := c1 or (dword(ch1) - byte('0') + 52);
'+' : c1 := c1 or 62;
'/' : c1 := c1 or 63;
else begin
if i2 = 3 then begin
po^[0] := c1 shr 16;
po^[1] := byte(c1 shr 8);
SetLength(result, Length(result) - 1);
end else begin
po^[0] := c1 shr 10;
SetLength(result, Length(result) - 2);
end;
exit;
end;
end;
if i2 = 3 then
break;
inc(i2);
c1 := c1 shl 6;
end;
po^[0] := c1 shr 16;
po^[1] := byte(c1 shr 8);
po^[2] := byte(c1);
inc(dword(pi), 4);
inc(dword(po), 3);
end;
end else
result := '';
end;
....
var a,b:string;
begin
a:='aaa';
b:=Encode( a );
showmessage( b );
a:=Decode( b );
showmessage( a );
کد: const
Codes64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/';
function Encode64(S: string): string;
var
i: Integer;
a: Integer;
x: Integer;
b: Integer;
begin
Result := '';
a := 0;
b := 0;
for i := 1 to Length(s) do
begin
x := Ord(s[i]);
b := b * 256 + x;
a := a + 8;
while a >= 6 do
begin
a := a - 6;
x := b div (1 shl a);
b := b mod (1 shl a);
Result := Result + Codes64[x + 1];
end;
end;
if a > 0 then
begin
x := b shl (6 - a);
Result := Result + Codes64[x + 1];
end;
end;
function Decode64(S: string): string;
var
i: Integer;
a: Integer;
x: Integer;
b: Integer;
begin
Result := '';
a := 0;
b := 0;
for i := 1 to Length(s) do
begin
x := Pos(s[i], codes64) - 1;
if x >= 0 then
begin
b := b * 64 + x;
a := a + 6;
if a >= 8 then
begin
a := a - 8;
x := b shr a;
b := b mod (1 shl a);
x := x mod 256;
Result := Result + chr(x);
end;
end
else
Exit;
end;
end;
|
|