Bibliotecas: Biblioteca de funções Hash

 

Biblioteca de funções Hash:

A biblioteca contém as seguintes funções hash: adler32, CRC-32, MaHash8v64. Além disso, ela possui funções para conversão de raíz de um número.
  • adler32
  • CRC-32 (rápida, implementação de tabela)
  • MaHash8v64 (rápida, implementação de tabela)

Todas as três funções são adaptados para strings Unicode em MQL5. Os resultados foram verificados com o Fsum Frontend 1.5.5.1.

Autor: Александр Чугунов

 

Boa tarde!

A tarefa é rastrear os momentos de mudança de um conjunto de coleções de objetos complexos. Posso converter um objeto e uma coleção em uma string, com cerca de 2.000 caracteres por coleção. Você pode me dizer qual função de biblioteca será mais correta para obter uma representação curta de uma cadeia tão longa?

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

Boa tarde!

A tarefa é rastrear os momentos de mudança de um conjunto de coleções de objetos complexos. Posso converter um objeto e uma coleção em uma string, com cerca de 2.000 caracteres por coleção. Você pode me dizer qual função de biblioteca será mais correta para obter uma representação curta de uma cadeia tão longa?

CryptEncode/Decode e escolha os métodos HASH_xxx.

Você pode até mesmo ZIP :-) um texto normal de 2.000 caracteres impressos tem apenas 200-300 bytes, cabendo em 4 long`es.

 

ErroCryptDecode(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);
}

---

A função CryptEncodeA cria uma cadeia de caracteres que, em seguida,CryptDecodeA não consegue descriptografar e apresenta um erro em mt4: "4029", em mt5: "4006". O terminal criptografou o que não pode ser descriptografado por ele mesmo.

Linha do registro: vj9jDk+GxxB4W1zQc4/rC4OPvttMcgcF5ZFVC7m7l50=

Se você remover o último "="-, ele será descriptografado e não haverá erro.

Ao mesmo tempo, o php decodifica normalmente e corretamente:

$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;

---

Criptografe a mesma cadeia de caracteres no servidor: "indicator_chart_window".

Obtenha o resultado:"vj9jDk+GxxB4W1zQc4/rC54fEtkLAsAONkyeprqmMlw=""

Inserimos essa linha no código mql e novamente recebemos um erro - remova o último "=" e tudo funcionará bem.

---

Coloquei uma chave de criptografia aleatória e, no servidor, a string é: "8CpXr3OlVhGs41syHA0+HqZKnatswQjRWn2fKYN4qN4=="

Inseri a string no mql-code - erro, removi um "=" deixando apenas um - funcionou bem (qual foi a chave que criou uma string com dois iguais - não consegui reproduzir)

Quero obter uma resposta, talvez eu esteja fazendo algo errado!

P.S. Anexei todos os códigos, qual pode ser o problema?
 

A função StringToArray captura a terminação zero se você não especificar o comprimento da string (historicamente)

Portanto, na função CryptDecodeA, você deve usar

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

em vez de

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

A função StringToArray captura a terminação zero se você não especificar o comprimento da string (historicamente)

Portanto, na função CryptDecodeA, é necessário usar

em vez de

@Ilyas

Verifiquei isso em diferentes variações - tudo funciona.

Ainda há um problema:

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

Como remover caracteres não impressos?

Obrigado!

 
Vitaly Muzichenko:

@Ilyas

Verificado em diferentes variações - tudo funciona.

Ainda há um problema:

Como remover caracteres não impressos?

Muito obrigado!

Não há nenhuma função no MQL com a funcionalidade de que você precisa

É mais fácil fazer isso antes de converter a matriz em uma string:

//+------------------------------------------------------------------+
//|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);
//--- nenhum dado para converter
   if(start>=input_size || count==0)
      return(NULL);
//--- corrigir o parâmetro de início
   if(start<0)
      start=0;
//--- corrigir o parâmetro de contagem
   if(count<0 || count==WHOLE_ARRAY || (start+count)>input_size)
      count=input_size-start;
//--- converter a matriz de entrada como ela é
   if(!remove_non_printable)
      return(cvt::convert(input_array,start,count,codepage));
//--- remover símbolos não imprimíveis da matriz de entrada
   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++];
      //--- verifique se há negativo, input_array pode ser assinado
      if(input_sym>0 && input_sym<' ')
         continue;
      //--- zero é o terminador
      if(input_sym==0)
         break;
      //--- copiar o símbolo de entrada
      cvt_array[cvt_size++]=input_sym;
     }
//--- converter matriz limpa em string
   return(cvt::convert(cvt_array,0,cvt_size));
  }
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
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));
  }
//+------------------------------------------------------------------+