Библиотеки: Библиотека хеш-функций и конвертаций в другие системы исчисления

 

Библиотека хеш-функций и конвертаций в другие системы исчисления:

В библиотеке содержатся алгоритмы хеш-функции общего назначения: adler32, CRC-32, MaHash8v64. А также функции преобразования из десятичной системы исчисления в строковое представление в Base системе исчисления и наоборот.

Перевод из одной системы исчисления в другую строится на строке символов (нестандартная после 37): 10 [0..9] + 26 [A..Z] + 26 [a..z] + 33 [А..Я] + 33 [а..я]. Т.е. при использовании до 36 включительно системы исчисления используются арабские цифры и заглавные буквы английского алфавита.

Практическим применением большой системы исчисления может быть компрессия знаков для применения в наименовании графических объектов.

Автор: Александр

 

Добрый день!

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

Документация по MQL5: Основы языка / Типы данных / Тип string
Документация по MQL5: Основы языка / Типы данных / Тип string
  • www.mql5.com
Тип string предназначен для хранения текстовых строк. Текстовая строка представляет собой последовательность символов в формате Unicode с завершающим нулем на конце. string-переменной может быть назначена строковая константа. Строковая константа представляет собой последовательность символов Unicode, заключенную в двойные кавычки: "Это...
 
Nikolai Karetnikov:

Добрый день!

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

CryptEncode/Decode и на выбор методы HASH_xxx

можно даже ZIP :-) регулярный текст 2000 печатных символов это какой-то мизер - 200-300 байт, в 4 long`а могут поместится

 

Ошибка CryptDecode(CRYPT_BASE64

int OnInit()
{
   string text="";
   string res="";
   string key="fuyTkH3cd63K9Htrl2xdFgjerPjmla8h";

   text="indicator_chart_window";
   if(!CryptEncodeA(text,key,res))
      Print("Error: Encode:",GetLastError());

   Print(res);

   text="vj9jDk+GxxB4W1zQc4/rC4OPvttMcgcF5ZFVC7m7l50=";
   if(!CryptDecodeA(text,key,res))
      Print("Error: Decode:",GetLastError());

   Print(res);
   return(INIT_SUCCEEDED);
}

//------------------------------------------------------------------
bool CryptEncodeA(string InputText,string key,string &Output) {
   uchar scr[];
   uchar dst[];
   uchar res[];
   uchar key_aes256[];
   uchar key_base64[];
   StringToCharArray(InputText,scr);
   StringToCharArray(key,key_aes256);
   if(CryptEncode(CRYPT_AES256,scr,key_aes256,dst)==0) return(false);
   if(CryptEncode(CRYPT_BASE64,dst,key_base64,res)==0) return(false);
   Output = CharArrayToString(res);
   return(true);
}
//--
bool CryptDecodeA(string InputText,string key,string &Output) {
   uchar scr[];
   uchar dst[];
   uchar res[];
   uchar key_base64[];
   uchar key_aes256[];
   StringToCharArray(InputText,scr);
   StringToCharArray(key,key_aes256);
   if(CryptDecode(CRYPT_BASE64,scr,key_base64,dst)==0) return(false);
   if(CryptDecode(CRYPT_AES256,dst,key_aes256,res)==0) return(false);
   Output = CharArrayToString(res);
   return(true);
}

---

Функция CryptEncodeA создаёт строку, которую потом CryptDecodeA не может расшифровать и выдаёт ошибку в мт4: "4029", в мт5: "4006". Терминал зашифровал, что сам не может дешифровать.

Строка с журнала: vj9jDk+GxxB4W1zQc4/rC4OPvttMcgcF5ZFVC7m7l50=

Если убрать последнее "="- тогда расшифрует и ошибки нет.

При этом, php расшифровывает нормально и правильно:

$secret_key = 'fuyTkH3cd63K9Htrl2xdFgjerPjmla8h';

$s = "indicator_chart_window";
$res = base64_encode(openssl_encrypt($s,"AES-256-ECB",$secret_key,OPENSSL_RAW_DATA));
echo $res.'<br>';

$s= "vj9jDk+GxxB4W1zQc4/rC54fEtkLAsAONkyeprqmMlw=";
$res = openssl_decrypt(base64_decode($s),"AES-256-ECB",$secret_key,OPENSSL_ZERO_PADDING|OPENSSL_RAW_DATA);
echo $res;

---

Шифруем на сервере ту-же строку: "indicator_chart_window"

Получаем результат: "vj9jDk+GxxB4W1zQc4/rC54fEtkLAsAONkyeprqmMlw="

Вставляем эту строку в mql-код и снова ошибка - убираем последнее "=" и всё работает нормально.

---

Поставил какой-то случайный ключ шифрования, на сервере строка получилась: "8CpXr3OlVhGs41syHA0+HqZKnatswQjRWn2fKYN4qN4=="

Вставил строку в mql-код - ошибка, убрал одно "=" оставив только одно - сработало нормально (какой был ключ что создалась строка с двумя равно - воспроизвести не смог)

Хочу получить ответ, может что делаю не так!

P.S. Все коды приложил, в чём может быть проблема?
 

Функция StringToArray захватывает терминирующий ноль, если не указывать длину строки (сложилось исторически)

Поэтому, в функции CryptDecodeA нужно использовать

StringToCharArray(InputText,scr,0,StringLen(InputText));

вместо

StringToCharArray(InputText,scr);
Документация по MQL5: Общие функции / CryptDecode
Документация по MQL5: Общие функции / CryptDecode
  • www.mql5.com
CryptDecode - Общие функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Ilyas:

Функция StringToArray захватывает терминирующий ноль, если не указывать длину строки (сложилось исторически)

Поэтому, в функции CryptDecodeA нужно использовать

вместо

@Ilyas

Проверял в разных вариациях - всё работает.

Осталась одна проблема:

StringReplace(res,"\x00..\x1F",""); // Не помогает

Как удалить непечатные символы?

Спасибо!

 
Vitaly Muzichenko:

@Ilyas

Проверял в разных вариациях - всё работает.

Осталась одна проблема:

Как удалить непечатные символы?

Спасибо!

В MQL нет функции с нужным Вам функционалом

Сделать это проще до конвертации массива в строку:

//+------------------------------------------------------------------+
//|                                                ArrayToString.mq5 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template<typename TChar>
string ArrayToString(const TChar &input_array[],bool remove_non_printable=false,int start=0,int count=-1,int codepage=CP_ACP)
  {
   struct cvt
     {
      static string convert(const uchar &input_array[],int start=0,int count=-1,int codepage=CP_ACP) { return(CharArrayToString(input_array,start,count,codepage)); }
      static string convert(const short &input_array[],int start=0,int count=-1,int codepage=CP_ACP) { return(ShortArrayToString(input_array,start,count)); }      
     };
  
   int input_size =ArraySize(input_array);
//--- no data to convert
   if(start>=input_size || count==0)
      return(NULL);
//--- fix start parameter
   if(start<0)
      start=0;
//--- fix count parameter
   if(count<0 || count==WHOLE_ARRAY || (start+count)>input_size)
      count=input_size-start;
//--- convert input array as it is
   if(!remove_non_printable)
      return(cvt::convert(input_array,start,count,codepage));
//--- remove non printable symbols from input array
   TChar cvt_array[];
   int   cvt_size=0;

   if(!ArrayResize(cvt_array,input_size))
      return(NULL);

   for(int i=0,n=start; i<input_size; i++)
     {
      const TChar input_sym = input_array[n++];
      //--- check for negative, input_array can be signed
      if(input_sym>0 && input_sym<' ')
         continue;
      //--- zero is terminator
      if(input_sym==0)
         break;
      //--- copy input symbol
      cvt_array[cvt_size++]=input_sym;
     }
//--- convert cleaned array to string
   return(cvt::convert(cvt_array,0,cvt_size));
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   uchar input_array_uc[]= { 1, 'T', 2, 'h', 3, 'e', 4, ' ', 5, 'q', 6, 'u', 7, 'i', 8, 'c', 9, 'k', 10, ' ', 11, 'b', 12, 'r', 13, 'o', 14, 'w', 15, 'n', 16, ' ', 15, 'f', 16, 'o', 17, 'x', 18, ' ', 19, 'j', 20, 'u',
                            21, 'm', 22, 'p', 23, 's', 24, ' ', 25, 'o', 26, 'v', 27, 'e', 28, 'r', 29, ' ', 30, 't', 31, 'h','e',' ','l','a','z','y',' ','d','o','g','.', 0, 'X', 'X', 'X', 'X', 'X', 'X' };
   short input_array_s []= { 1, 'T', 2, 'h', 3, 'e', 4, ' ', 5, 'q', 6, 'u', 7, 'i', 8, 'c', 9, 'k', 10, ' ', 11, 'b', 12, 'r', 13, 'o', 14, 'w', 15, 'n', 16, ' ', 15, 'f', 16, 'o', 17, 'x', 18, ' ', 19, 'j', 20, 'u',
                            21, 'm', 22, 'p', 23, 's', 24, ' ', 25, 'o', 26, 'v', 27, 'e', 28, 'r', 29, ' ', 30, 't', 31, 'h','e',' ','l','a','z','y',' ','d','o','g','.', 0, 'X', 'X', 'X', 'X', 'X', 'X' };

   Print("without removing non-printables");
   Print(ArrayToString(input_array_uc));
   Print(ArrayToString(input_array_s));

   Print("with removing non-printables");
   Print(ArrayToString(input_array_uc,true));
   Print(ArrayToString(input_array_s,true));
  }
//+------------------------------------------------------------------+
Причина обращения: