StranikS_Scan Posted December 19, 2019 Share Posted December 19, 2019 Сел делать новый 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 подмогни обратную функцию написать )))) 4 @ Link to comment Short link Share on other sites More sharing options...
ktulho Posted December 19, 2019 Share Posted December 19, 2019 (edited) 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. Вроде работает. Только надо проверки добавить, ну и по компактнее можно записать наверное. Edited December 19, 2019 by ktulho 2 @ Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted December 19, 2019 Author Share Posted December 19, 2019 Отлично! Спасибо. Link to comment Short link Share on other sites More sharing options...
StranikS_Scan Posted December 29, 2019 Author Share Posted December 29, 2019 Тема закрыта. Выкладываю итоговый вариант кода ниже, может кому пригодится. 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; 1 @ Link to comment Short link Share on other sites More sharing options...
Recommended Posts