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?
- www.mql5.com
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);
- www.mql5.com
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
Verifiquei isso em diferentes variações - tudo funciona.
Ainda há um problema:
StringReplace(res,"\x00..\x1F",""); // Не помогает
Como remover caracteres não impressos?
Obrigado!
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)); } //+------------------------------------------------------------------+
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso
Biblioteca de funções Hash:
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: Александр Чугунов