Если вам нужно кодировать с помощью Base64 с помощью ключа, то на самом деле это не сложно сделать, даже если это не определено в стандарте.
Base64 использует алфавит из 64 символов. Первые 62 символа - это маленькие и заглавные буквы английского алфавита, а также цифры от 0 до 9. Последние 2 символа чаще всего представляют собой + и /, но они могут отличаться в разных реализациях.
Итак, теперь поймите, что когда вы разбиваете свою строку на биты и перегруппируете их, используя 6 бит вместо 8 на символ, вы всегда сможете найти символ в вашем алфавите, потому что 6-битные числа имеют ровно 64 разных возможные значения. Base64 просто перечисляет символы от% 000000 (0) до 111111 (63). Но вы можете использовать ключ во время поиска этого символа. Скажем, ваше 6-битное число% 000011 (3), поэтому оно будет индексировать 4-й символ в вашем алфавите. Но теперь вы можете использовать свой ключ, чтобы изменить этот индекс, переместить его влево или вправо на (например) количество позиций, равное ASCII-коду символа вашего ключа (8-битное число). Всякий раз, когда ваш индекс выходит за пределы диапазона (ниже 0 или выше 63), вы просто телепортируете его на противоположную сторону диапазона. И если вы переместили индекс вправо во время кодирования, используйте левое направление для декодирования (и наоборот). По сути, вы скремблируете поиск символов с помощью шаблона, определяемого символами вашей клавиши.
Итак, вы просто используете кодирование Base64 с ключом (вместо того, чтобы сначала вводить ввод, а затем кодировать). Не за что.
И так как вы попросили пример кода, ниже приведен быстрый пример Object Pascal, который я написал. Этот код может быть быстрее, если вы сначала выделите память для последней строки, а затем запишете ее вместо конкатенации со строкой в цикле, которая каждый раз перераспределяет память - но вы можете сами разобраться, если вам это нужно для лучшей производительности:
const
C_ALPHABIG = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
C_ALPHASMALL = 'abcdefghijklmnopqrstuvwxyz';
C_ALPHA = C_ALPHABIG+C_ALPHASMALL;
C_DIGITS = '0123456789';
C_SYMBOLS = '+/';
C_ALPHABET = C_ALPHA+C_DIGITS+C_SYMBOLS;
type
TIndexShiftDirection = (isdLeft, isdRight);
Function ShiftSymbolIndex(const AIndex: integer; const AKey: string; var ACurrentKeyPos: integer; const ADirection: TIndexShiftDirection): integer;
begin
Result := AIndex; if(AKey='')then exit;
if(ACurrentKeyPosLength(AKey))then ACurrentKeyPos := 1;
if(ADirection=isdRight)
then begin
Result := Result+Ord(AKey[ACurrentKeyPos]);
if(Result>64)then Result := Result mod 64;
if(Result=0)then Result :=64;
end
else begin
Result := Result-Ord(AKey[ACurrentKeyPos]);
if(Result=Length(AKey))
then ACurrentKeyPos := 1
else inc(ACurrentKeyPos);
end;
Function Encode64(const s: string; const Key: string): string;
var
i,n,p,k : integer;
a,b,c,d : byte;
begin
Result := ''; k := 1; if(s='')then exit;
n := Length(s)div 3;
if(n>0)then for i:=0 to n-1 do
begin
p := (i*3)+1;
a := (ord(s[p])shr 2); inc(a);
b := ((ord(s[p])and %00000011)shl 4)+(ord(s[p+1])shr 4); inc(b);
c := ((ord(s[p+1])and %00001111)shl 2)+(ord(s[p+2])shr 6); inc(c);
d := ord(s[p+2])and %00111111; inc(d);
//
a := ShiftSymbolIndex(a,key,k, isdRight);
b := ShiftSymbolIndex(b,key,k, isdRight);
c := ShiftSymbolIndex(c,key,k, isdRight);
d := ShiftSymbolIndex(d,key,k, isdRight);
//
Result := Result
+ C_ALPHABET[a]
+ C_ALPHABET[b]
+ C_ALPHABET[c]
+ C_ALPHABET[d];
end;
n := Length(s)-(n*3);
if(n=0)then begin {Result := Result+'0';} exit; end;
case n of
1: begin
p := Length(s);
a := (ord(s[p])shr 2); inc(a); a := ShiftSymbolIndex(a,key,k, isdRight);
b := (ord(s[p])and %00000011); inc(b); b := ShiftSymbolIndex(b,key,k, isdRight);
Result := Result
+ C_ALPHABET[a]
+ C_ALPHABET[b]
{+ '2'};//if Length(endoced_str)mod 4 = 2, then this case is true
end;
2: begin
p := Length(s)-1;
a := (ord(s[p])shr 2);
b := ((ord(s[p])and %00000011)shl 4)+(ord(s[p+1])shr 4);
c := (ord(s[p+1])and %00001111);
inc(a); a := ShiftSymbolIndex(a,key,k, isdRight);
inc(b); b := ShiftSymbolIndex(b,key,k, isdRight);
inc(c); c := ShiftSymbolIndex(c,key,k, isdRight);
Result := Result
+ C_ALPHABET[a]
+ C_ALPHABET[b]
+ C_ALPHABET[c]
{+ '4'};//if Length(endoced_str)mod 4 = 3, then this case is true
end;
end;
end;
Function Decode64(const s: string; const Key: string): string;
var
n,i,p,k : integer;
a,b,c,d : byte;
begin
Result := ''; k:=1; if(s='')then exit;
n := Length(s)div 4;
if(n>0)then for i:=0 to n-1 do
begin
p := (i*4)+1;
a := Pos(s[p],C_ALPHABET); a := ShiftSymbolIndex(a,key,k, isdLeft);
b := Pos(s[p+1],C_ALPHABET); b := ShiftSymbolIndex(b,key,k, isdLeft);
c := Pos(s[p+2],C_ALPHABET); c := ShiftSymbolIndex(c,key,k, isdLeft);
d := Pos(s[p+3],C_ALPHABET); d := ShiftSymbolIndex(d,key,k, isdLeft);
if(a*b*c*d=0)then begin Result := ''; exit; end; //cannot be, if symbols are valid
Result := Result
+ chr(((a-1)shl 2) + ((b-1)shr 4))
+ chr((((b-1)and %001111)shl 4) + ((c-1)shr 2))
+ chr((((c-1)and %000011)shl 6) + (d-1));
end;
n := Length(s)mod 4;
if(n=0)then exit;
case n of
2: begin
p := Length(s)-1;
a := Pos(s[p],C_ALPHABET); a := ShiftSymbolIndex(a,key,k, isdLeft);
b := Pos(s[p+1],C_ALPHABET); b := ShiftSymbolIndex(b,key,k, isdLeft);
if(a*b=0)then begin Result := ''; exit; end; //cannot be, if symbols are valid
Result := Result
+ chr(((a-1)shl 2) + (b-1));
end;
3: begin
p := Length(s)-2;
a := Pos(s[p],C_ALPHABET);
b := Pos(s[p+1],C_ALPHABET);
c := Pos(s[p+2],C_ALPHABET);
if(a*b*c=0)
then begin Result := ''; exit; end; //cannot be, if symbols are valid
a := ShiftSymbolIndex(a,key,k, isdLeft);
b := ShiftSymbolIndex(b,key,k, isdLeft);
c := ShiftSymbolIndex(c,key,k, isdLeft);
Result := Result
+ chr(((a-1)shl 2) + ((b-1)shr 4))
+ chr((((b-1)and %001111)shl 4) + (c-1));
end;
else Result := '';
end;
end;
Обратите внимание на функцию ShiftSymbolIndex - это скремблер поиска символов, он может перемещать индекс символа вправо или влево. Я использую право в кодировщике, а слева в кодировщике, но все зависит от вас.
Если вы пропустите ключевой аргумент в функции Encode64 или Decode64 (или если вы передадите пустой строковый ключ), вы получите кодировку / декодирование Base64 по умолчанию.
Кроме того, этот кодер не добавляет отступы (символы "=") к кодированной строке base64. Заполнение не требуется для декодирования, если только ваш декодер не работает в строгом режиме (этот кодер не используется) - но это вы сами можете выяснить.