Jump to content
Korean Random
StranikS_Scan

Зная ByteArrayToBase64 нужно написать обратную функцию

Recommended Posts

Сел делать новый MCTCreator и обнаружил, что в упакованных визуалах сейчас могут встречаться иногда имена свойств, закодированные под псевдо-Base64. Рабочая функция для их распаковки в исходный текст на Делфи у меня есть. Однако, нужна помощь написать обратную функцию, запаковывающую строку в кодированный массив байт.

 

Например, есть Gun_01.visual_processed -----> .... 72 B6 AC 85 38 A5 78 C6 A9 .... -----> 'crashTileMap'

 

Функция для распаковки ниже.

  const IntToBase64: array[0..63] of Char = ('A','B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                                             'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                             'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                                             'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                             'w', 'x', 'y','z', '0', '1', '2', '3', '4', '5', '6','7', '8',
                                             '9','+', '/');

  function ByteArrayToBase64(const A: array of ShortInt; const Len: Integer): string;
  var inCursor, i: Integer;
      Byte0, Byte1, Byte2: Byte;
  begin
  Result:='';
  inCursor:=0;
  for i:=1 to (Len div 3) do
   begin
   Byte0:=(A[inCursor] and $FF);
   Inc(inCursor);
   Byte1:=(A[inCursor] and $FF);
   Inc(inCursor);
   Byte2:=(A[inCursor] and $FF);
   Result:=Result+IntToBase64[Byte0 shr 2];
   Result:=Result+IntToBase64[(Byte0 shl 4) and $3f or (Byte1 shr 4)];
   Result:=Result+IntToBase64[(Byte1 shl 2) and $3f or (Byte2 shr 6)];
   Result:=Result+IntToBase64[Byte2 and $3f];
   end;
  end;

//Пример
var s: array of ShortInt;
    f:string;

SetLength(s,9);
s[0]:=ShortInt($72);
s[1]:=ShortInt($B6);
s[2]:=ShortInt($AC);
s[3]:=ShortInt($85);
s[4]:=ShortInt($38);
s[5]:=ShortInt($A5);
s[6]:=ShortInt($78);
s[7]:=ShortInt($C6);
s[8]:=ShortInt($A9);
f:=byteArrayToBase64(s,9);

 

@SkepticalFox подмогни обратную функцию написать ))))

  • Upvote 4

Share this post


Link to post

Short link
Share on other sites
var s, s1: ShortString;
    ch: AnsiChar;
    i: Integer;
    j: UInt32;

const IntToBase64: array[0..63] of AnsiChar = ('A','B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                                             'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                             'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                                             'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                             'w', 'x', 'y','z', '0', '1', '2', '3', '4', '5', '6','7', '8',
                                             '9','+', '/');


function index(_ch: AnsiChar):Byte;
var _i: Integer;
begin
  _i := 0;
  Result := 64;
  while (_i < 64) and (Result > 63) do
    begin
      if _ch = IntToBase64[_i] then
        Result := _i;
      Inc(_i);
    end;

end;

begin
  s1 := '';
  s := 'crashTileMap';
  I := 1;
  while I < Length(s) + 1 do
    begin
      j := 0;
      j := index(s[I]);
      Inc(I);
      j := (j shl 6) or index(s[I]);
      Inc(I);
      j := (j shl 6) or index(s[I]);
      Inc(I);
      j := (j shl 6) or index(s[I]);
      Inc(I);
      s1 := s1 + copy(IntToHex(j), 3, 6);
    end;
  writeln(s1);
  readln;
end.

Вроде работает. Только надо проверки добавить, ну и по компактнее можно записать наверное.

image.png.d6a889a7c7cede3a583c79f703c75d16.png

Edited by ktulho
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

Тема закрыта.

 

Выкладываю итоговый вариант кода ниже, может кому пригодится.

 

const IntToBase64: array[0..63] of Char = ('A','B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                                           'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                                           'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                                           'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
                                           'w', 'x', 'y','z', '0', '1', '2', '3', '4', '5', '6','7', '8',
                                           '9','+', '/');

function ByteArrayToBase64(const A: TBytesArray): string;
var numFullGroups, numBytesInPartialGroup,
    inCursor, i: Integer;
    Byte0, Byte1, Byte2: Byte;
begin
Result:='';
numFullGroups:=Length(A) div 3;
numBytesInPartialGroup:=Length(A) mod 3;
inCursor:=-1;
for i:=1 to numFullGroups do
 begin
 Inc(inCursor);
 Byte0:=(A[inCursor] and $FF);
 Inc(inCursor);
 Byte1:=(A[inCursor] and $FF);
 Inc(inCursor);
 Byte2:=(A[inCursor] and $FF);
 Result:=Result+IntToBase64[Byte0 shr 2];
 Result:=Result+IntToBase64[(Byte0 shl 4) and $3f or (Byte1 shr 4)];
 Result:=Result+IntToBase64[(Byte1 shl 2) and $3f or (Byte2 shr 6)];
 Result:=Result+IntToBase64[Byte2 and $3f];
 end;
if numBytesInPartialGroup<>0 then
 begin
 Inc(inCursor);
 Byte0:=(A[inCursor] and $FF);
 Result:=Result+IntToBase64[Byte0 shr 2];
 if numBytesInPartialGroup=1 then
  begin
  Result:=Result+IntToBase64[(Byte0 shl 4) and $3f];
  Result:=Result+'==';
  end
 else begin
      Inc(inCursor);
      Byte1:=(A[inCursor] and $FF);
      Result:=Result+IntToBase64[(Byte0 shl 4) and $3f or (Byte1 shr 4)];
      Result:=Result+IntToBase64[(Byte1 shl 2) and $3f];
      Result:=Result+'=';
      end;
end;
end;

function Base64ToByteArray(const S: string): TBytesArray;
  function GetIndex(C: Char): Byte;
  begin
  Result:=0;
  while Result<64 do
   begin
   if C=IntToBase64[Result] then Break;
   Inc(Result);
   end;
  end;

var i, k: Integer;
    j: Cardinal;
begin
if (Length(S) mod 4)=0 then
 begin
 i:=1;
 k:=0;
 SetLength(Result, (Length(S)*3) div 4);
 while i<=Length(S) do
  begin
  j:=GetIndex(S[i]);
  Inc(i);
  j:=(j shl 6) or GetIndex(S[i]);
  Inc(i);
  j:=(j shl 6) or GetIndex(S[i]);
  Inc(i);
  j:=(j shl 6) or GetIndex(S[i]);
  Inc(i);
  Result[k]:=(j shr $10) and $FF;
  Inc(k);
  Result[k]:=(j shr $8) and $FF;
  Inc(k);
  Result[k]:=j and $FF;
  Inc(k);
  end;
 end
else SetLength(Result, 0);
end;

 

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...