Bibliotecas: Librería de funciones hash

 

Librería de funciones hash:

La bibrería contiene las siguientes funciones hash: adler32, CRC-32, MaHash8v64. También tiene funciones para la convertir la raíz de un número.

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

 

Buenas tardes.

La tarea consiste en seguir los momentos de cambio de un conjunto de colecciones de objetos complejos. Puedo convertir un objeto y una colección en una cadena, serán unos 2000 caracteres por colección. ¿Pueden decirme qué función de biblioteca será más correcta para obtener una representación corta de una cadena tan larga?

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

¡Buenas tardes!

La tarea consiste en seguir los momentos de cambio de un conjunto de colecciones de objetos complejos. Puedo convertir un objeto y una colección en una cadena, serán unos 2000 caracteres por colección. ¿Pueden decirme qué función de biblioteca será más correcta para obtener una representación corta de una cadena tan larga?

CryptEncode/Decode y elige los métodos HASH_xxx.

puedes incluso ZIP :-) un texto normal de 2000 caracteres imprimibles son unos míseros 200-300 bytes, puede caber en 4 long`es.

 

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

---

La función CryptEncodeA crea una cadena, que luegoCryptDecodeA no puede descifrar y da un error en mt4: "4029", en mt5: "4006". El terminal ha cifrado que no puede descifrar por sí mismo.

Línea del registro: vj9jDk+GxxB4W1zQc4/rC4OPvttMcgcF5ZFVC7m7l50=

Si quitas el último "="- entonces se desencripta y no hay error.

Al mismo tiempo, php descifra normal y correctamente:

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

---

Cifra la misma cadena en el servidor: "indicator_chart_window".

Obtener el resultado:"vj9jDk+GxxB4W1zQc4/rC54fEtkLAsAONkyeprqmMlw=""

Insertamos esta línea en el código mql y de nuevo obtenemos un error - eliminamos el último "=" y todo funciona correctamente.

---

Pongo alguna clave de encriptación aleatoria, en el servidor la cadena es: "8CpXr3OlVhGs41syHA0+HqZKnatswQjRWn2fKYN4qN4=="

Inserté la cadena en mql-code - error,quité un "=" dejando sólo uno - funcionó bien (cuál fue la clave que creó una cadena con dos iguales - no pude reproducirlo).

¡Quiero obtener una respuesta, tal vez estoy haciendo algo mal!

P.D. He adjuntado todos los códigos, ¿cuál podría ser el problema?
 

La función StringToArray captura la terminación cero si no se especifica la longitud de la cadena (históricamente)

Por lo tanto, en la función CryptDecodeA debe utilizar

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

en lugar de

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

La función StringToArray captura la terminación cero si no se especifica la longitud de la cadena (históricamente)

Por lo tanto, en la función CryptDecodeA es necesario utilizar

en lugar de

@Ilyas

Lo he comprobado en diferentes variaciones - todo funciona.

Queda un problema:

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

¿Cómo eliminar los caracteres no imprimibles?

¡Gracias!

 
Vitaly Muzichenko:

@Ilyas

Comprobado en diferentes variaciones - todo funciona.

Queda un problema:

¿Cómo eliminar los caracteres no imprimibles?

Gracias.

No hay ninguna función en MQL con la funcionalidad que necesita

Es más fácil hacerlo antes de convertir el array a cadena:

//+------------------------------------------------------------------+
//|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 hay datos para convertir
   if(start>=input_size || count==0)
      return(NULL);
//--- fijar parámetro de inicio
   if(start<0)
      start=0;
//--- fijar parámetro de recuento
   if(count<0 || count==WHOLE_ARRAY || (start+count)>input_size)
      count=input_size-start;
//--- convertir array de entrada tal cual
   if(!remove_non_printable)
      return(cvt::convert(input_array,start,count,codepage));
//--- eliminar símbolos no imprimibles de la 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++];
      //--- comprobar negativo, input_array puede tener signo
      if(input_sym>0 && input_sym<' ')
         continue;
      //--- el cero es el terminador
      if(input_sym==0)
         break;
      //--- copiar símbolo de entrada
      cvt_array[cvt_size++]=input_sym;
     }
//--- convertir array limpiado a cadena
   return(cvt::convert(cvt_array,0,cvt_size));
  }
//+------------------------------------------------------------------+
//| Función de inicio del 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));
  }
//+------------------------------------------------------------------+