|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Base64 Encoder / Decoder
Кодер / декодер в Base64.
Возможно кому-то пригодится... Код:
{ Encoder / Decoder Base64 } unit EDBase64; interface { Base64encode Base64decode Base64URLencode } function Base64encode(const Data: PAnsiChar; const DataSize: integer): AnsiString; function Base64URLencode(const Data: PAnsiChar; const DataSize: integer): AnsiString; function Base64decode(const Data: PAnsiChar; const DataSize: integer): AnsiString; implementation const Base64Table : array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; Base64URLTable : array[0..63] of AnsiChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; b64FillChar = '='; b64Mask1 = $FC000000; b64Mask2 = $03F00000; b64Mask3 = $000FC000; b64Mask4 = $00003F00; type PBytes = ^TBytes; TBytes = packed array[0..0] of byte; b64IntChar = packed record case integer of 0: (l : integer); 1: (c : array[0..3] of AnsiChar); end; const _FI1 : packed array['A'..'Z'] of byte = (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); _FI2 : packed array['a'..'z'] of byte = (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); _FI3 : packed array['0'..'9'] of byte = (52,53,54,55,56,57,58,59,60,61); function FastIndexOf(const C: AnsiChar): integer; begin case byte(C) of $2B,$2D {+-} : result := 62; $2F,$5F {/_} : result := 63; $30..$39 {'0'..'9'} : result := _FI3[C]; $41..$5A {'A'..'Z'} : result := _FI1[C]; $61..$7A {'a'..'z'} : result := _FI2[C]; end; end; function Base64encode(const Data: PAnsiChar; const DataSize: integer): AnsiString; var trail, sz, i, k : integer; b64 : b64IntChar; pR : PAnsiChar; begin sz := (DataSize div 3) shl 2; trail := DataSize mod 3; if trail <> 0 then inc(sz, 4); SetLength(result, sz); pR := PAnsiChar(result); i := 0; k := 0; while (i < (DataSize-trail)) do begin b64.c[3] := Data[i]; b64.c[2] := Data[i+1]; b64.c[1] := Data[i+2]; inc(i, 3); pR[k] := Base64Table[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64Table[(b64.l and b64Mask2) shr 20]; pR[k+2] := Base64Table[(b64.l and b64Mask3) shr 14]; pR[k+3] := Base64Table[(b64.l and b64Mask4) shr 8]; inc(k,4); end; b64.l := 0; case trail of 1 : begin b64.c[3] := Data[i]; pR[k] := Base64Table[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64Table[(b64.l and b64Mask2) shr 20]; pR[k+2] := b64FillChar; pR[k+3] := b64FillChar; end; 2 : begin b64.c[3] := Data[i]; b64.c[2] := Data[i+1]; pR[k] := Base64Table[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64Table[(b64.l and b64Mask2) shr 20]; pR[k+2] := Base64Table[(b64.l and b64Mask3) shr 14]; pR[k+3] := b64FillChar; end; end; end; function Base64URLencode(const Data: PAnsiChar; const DataSize: integer): AnsiString; var trail, sz, i, k : integer; b64 : b64IntChar; pR : PAnsiChar; begin sz := (DataSize div 3) shl 2; trail := DataSize mod 3; if trail <> 0 then inc(sz, 4); SetLength(result, sz); pR := PAnsiChar(result); i := 0; k := 0; while (i < (DataSize-trail)) do begin b64.c[3] := Data[i]; b64.c[2] := Data[i+1]; b64.c[1] := Data[i+2]; inc(i, 3); pR[k] := Base64URLTable[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64URLTable[(b64.l and b64Mask2) shr 20]; pR[k+2] := Base64URLTable[(b64.l and b64Mask3) shr 14]; pR[k+3] := Base64URLTable[(b64.l and b64Mask4) shr 8]; inc(k,4); end; b64.l := 0; case trail of 1 : begin b64.c[3] := Data[i]; pR[k] := Base64URLTable[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64URLTable[(b64.l and b64Mask2) shr 20]; pR[k+2] := b64FillChar; pR[k+3] := b64FillChar; end; 2 : begin b64.c[3] := Data[i]; b64.c[2] := Data[i+1]; pR[k] := Base64URLTable[(b64.l and b64Mask1) shr 26]; pR[k+1] := Base64URLTable[(b64.l and b64Mask2) shr 20]; pR[k+2] := Base64URLTable[(b64.l and b64Mask3) shr 14]; pR[k+3] := b64FillChar; end; end; end; function Base64decode(const Data: PAnsiChar; const DataSize: integer): AnsiString; var trail, szin, szout, i, k : integer; b64 : b64IntChar; pR : PAnsiChar; begin if Data[DataSize-1] = b64FillChar then begin if Data[DataSize-2] = b64FillChar then trail := 2 else trail := 1; end else trail := 0; if trail = 0 then szin := DataSize else szin := DataSize-4; szout := (szin shr 2) * 3; if Trail <> 0 then if Trail = 1 then inc(szout, 2) else inc(szout, 1); SetLength(result, szout); pR := PAnsiChar(result); i := 0; k := 0; while i < szin do begin b64.l := 0; b64.l := (FastIndexOf(Data[i]) shl 26) + (FastIndexOf(Data[i+1]) shl 20) + (FastIndexOf(Data[i+2]) shl 14) + (FastIndexOf(Data[i+3]) shl 8); inc(i, 4); pR[k] := b64.c[3]; pR[k+1] := b64.c[2]; pR[K+2] := b64.c[1]; inc(k, 3); end; b64.l := 0; case trail of 1 : begin b64.l := (FastIndexOf(Data[i]) shl 26) + (FastIndexOf(Data[i+1]) shl 20) + (FastIndexOf(Data[i+2]) shl 14); pR[k] := b64.c[3]; pR[K+1] := b64.c[2]; end; 2 : begin b64.l := (FastIndexOf(Data[i]) shl 26) + (FastIndexOf(Data[i+1]) shl 20); pR[k] := b64.c[3]; end; end; end; end. |
#2
|
||||
|
||||
Было бы полезно опубликовать и Base16, Base32, Base91. Если найду у себя - обязательно выложу.
Нет повести печальнее на свете, чем повесть о заклиневшем Resete. |
#3
|
||||
|
||||
Давай, не помешают.
|