English Русский 中文 Español Deutsch 日本語
preview
Implementação do algoritmo criptográfico SHA-256 do zero em MQL5

Implementação do algoritmo criptográfico SHA-256 do zero em MQL5

MetaTrader 5Exemplos |
69 6
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir

As conquistas no âmbito do MQL5 permitem implementar algoritmos criptográficos de forma eficiente sem recorrer a soluções de terceiros, aumentando a segurança, a otimização e a estabilidade. Entre as vantagens de uma implementação personalizada, estão a possibilidade de ajustá-la a tarefas específicas, eliminar vulnerabilidades e manter a eficiência constante em diferentes ambientes. A criptografia agora é parte integrante da API, da verificação de transações e da integridade dos dados, exigindo dos desenvolvedores um entendimento aprofundado desses algoritmos. A integração entre criptografia e sistemas de negociação tornou-se um aspecto essencial no desenvolvimento de plataformas modernas.


Problemas de compatibilidade de assinaturas de API

A principal razão para a implementação personalizada do SHA-256 é a incompatibilidade fundamental entre as funções de hash integradas ao MQL5 e os requisitos das bolsas de criptomoedas. Essa incompatibilidade se manifesta de várias maneiras críticas, impactando diretamente as operações de trading.

Quando as plataformas de negociação se comunicam com bolsas de criptomoedas, como a Binance ou a Bybit, por meio de API, elas precisam gerar assinaturas criptográficas que correspondam exatamente às expectativas da bolsa. Essas assinaturas comprovam a autenticidade de cada requisição, garantindo que ordens e outras operações confidenciais provenham de fontes autorizadas. No entanto, as funções criptográficas internas do MQL5 frequentemente produzem assinaturas diferentes daquelas geradas por implementações padrão em outras linguagens de programação.

Esse descompasso de assinaturas ocorre porque as bolsas de criptomoedas normalmente esperam que as assinaturas sejam geradas de acordo com certos padrões, muitas vezes baseados em implementações em linguagens como Python ou JavaScript. As funções internas do MQL5, embora voltadas a propósitos gerais, podem tratar de forma diferente alguns aspectos do processo de hash, tais como:

  1. Ordenação de bytes no processamento dos dados de entrada
  2. Implementações de preenchimento
  3. Tratamento da codificação de caracteres
  4. Representação de valores intermediários na memória
  5. Tratamento de caracteres especiais na string de entrada

Essas diferenças levam a uma série de problemas operacionais graves em ambientes de produção:

Em primeiro lugar, as bolsas rejeitam as requisições de API porque as assinaturas não correspondem aos valores esperados. Essa rejeição ocorre no nível de autenticação, antes mesmo que a lógica de negociação seja executada. Considere um cenário em que o algoritmo de trading identifica uma oportunidade lucrativa e tenta enviar uma ordem. Se a assinatura for inválida, a bolsa rejeita imediatamente a requisição, fazendo com que o sistema perca completamente a oportunidade de negociação.

Em segundo lugar, as falhas de autenticação ocorrem de forma consistente em diferentes tipos de chamadas de API. Mesmo operações simples, como obter o saldo da conta ou verificar o status de uma ordem, tornam-se impossíveis, pois a bolsa não consegue confirmar a autenticidade da solicitação. Isso cria um problema sistêmico que afeta todos os aspectos do funcionamento do sistema de trading.

Em terceiro lugar, o envio de ordens torna-se particularmente problemático. Ao tentar enviar ordens, assinaturas inválidas impedem a execução das transações, o que pode levar a:

  • Perda de pontos de entrada em negociações planejadas
  • Impossibilidade de encerrar posições quando necessário
  • Falhas em operações de gerenciamento de risco
  • Execução incompleta de estratégias de trading

Em quarto lugar, a verificação de mensagens torna-se pouco confiável. Muitas bolsas utilizam verificação baseada em hash para diversos tipos de mensagens e notificações. Resultados de hash inconsistentes significam que o sistema de trading não pode verificar essas mensagens de forma confiável, podendo perder atualizações importantes ou agir com base em informações não verificadas.

As consequências desses problemas de compatibilidade vão além das questões técnicas imediatas. Elas afetam toda a operação de trading de forma sutil, porém significativa:

  • As estratégias de trading não podem ser executadas de maneira confiável
  • Os sistemas de gerenciamento de risco podem não funcionar conforme o planejado
  • O monitoramento do sistema e o registro de logs tornam-se menos confiáveis
  • A integração com APIs de bolsa exige constantes buscas por soluções alternativas

Por exemplo, considere uma chamada típica de API para uma bolsa de criptomoedas. Os mesmos dados de entrada podem gerar assinaturas completamente diferentes:

Uso da função interna do MQL5:

void OnStart()
{
   // The text to hash
   string text = "Hello";
   string key_text = "key";   
   
   // Method 1: Using HashCalculate() - Returns uchar array
   uchar data[];
   uchar key[];
   uchar result[];
   StringToCharArray(text, data);
   StringToCharArray(key_text, key);
  
  int res =  CryptEncode(CRYPT_HASH_SHA256, data, key, result);
  
  Print(ArrayToHex(result));
}

/*Result
 D9D3734CD05564A131946ECF9E240E0319CA2F5BA321BD9F87D634A24A29EF4D
*/

Uso de uma implementação padrão:


import hashlib
import hmac

text = "Hello" #message
key = "key"  #password

hash_object = hmac.new(bytes(key, 'utf-8'), text.encode('utf-8'), hashlib.sha256)
hex_dig = hash_object.hexdigest()

hex_dig

##output >>> "c70b9f4d665bd62974afc83582de810e72a41a58db82c538a9d734c9266d321e"

As discrepâncias na formação das assinaturas podem causar falhas em sinais e estratégias de trading válidos. Diferentes bolsas podem impor requisitos únicos para as assinaturas, o que exige uma implementação flexível e configurável.

As implementações personalizadas de SHA-256 oferecem aos desenvolvedores a capacidade de controlar:

    A conformidade com requisitos específicos da bolsa.
    A adaptação a padrões em constante mudança.
    A eliminação de problemas relacionados a assinaturas.
    A garantia de consistência em todo o sistema de trading.

Esse controle é fundamental para o trading de alta frequência e para estratégias complexas, nas quais a confiabilidade e a velocidade são de importância primordial. Apesar da complexidade, soluções personalizadas aumentam a confiabilidade e a integração em sistemas de trading de produção.

Diferença entre as implementações de HMAC e SHA-256

  • O Python utiliza a biblioteca hmac, que executa o HMAC (código de autenticação de mensagens baseado em função hash). Isso não é apenas um hash de texto com uma chave, mas sim um processo combinado:
    1. A chave é complementada (ou truncada) até o tamanho necessário.
    2. São realizadas duas etapas de hash: primeiro com a chave e a mensagem, depois com a chave e o resultado intermediário.
  • O MQL5, nesse código, executa apenas o cálculo do SHA-256 por meio de CryptEncode() sem a implementação completa de HMAC. Isso significa que ele realiza apenas um hash simples do texto com a chave, e não um HMAC.

Considerações finais: O Python utiliza HMAC, enquanto o MQL5 utiliza apenas SHA-256, o que já garante resultados diferentes.


Otimização de eficiência: uma análise profunda

Ao implementar o SHA-256 em um ambiente de trading, a otimização da eficiência torna-se um fator decisivo, pois cada milissegundo pode afetar os resultados das negociações. A implementação personalizada oferece diversas maneiras de otimizar o desempenho que seriam impossíveis ao usar funções integradas.

Os sistemas de trading frequentemente apresentam padrões específicos em suas operações criptográficas. Por exemplo, as assinaturas de ordens normalmente contêm componentes semelhantes, como carimbos de tempo, símbolos e quantidades. Compreendendo esses padrões, podemos otimizar nossa implementação de SHA-256 de forma específica para estruturas de dados relacionadas ao trading.

Vejamos como ocorre o envio de ordens em um cenário típico de negociação. Para cada ordem, são necessários vários fragmentos de informação: o par de moedas, o tipo de ordem, a quantidade, o preço e o carimbo de tempo. Em implementações padrão, esses dados seriam processados como novas entradas a cada vez. No entanto, podemos otimizar esse processo reconhecendo que muitos componentes permanecem inalterados ou seguem padrões previsíveis.

Vejamos como essa otimização funciona na prática. Ao gerar assinaturas para ordens, grande parte da estrutura dos dados permanece igual:

baseEndpoint/symbol=BTCUSDT&side=BUY&type=LIMIT&quantity=0.1&price=50000&timestamp=1234567890

Nessa string, geralmente apenas alguns elementos mudam entre as ordens: a quantidade, o preço e o carimbo de tempo. Estruturando nossa implementação para processar de forma eficiente essas alterações parciais, é possível aumentar significativamente a eficiência. Isso pode incluir o seguinte:

  • A criação de funções especializadas de pré-processamento que tratam com eficiência as estruturas comuns de dados de trading,
  • a implementação de um gerenciamento inteligente de buffer para componentes frequentemente utilizados,
  • e o desenvolvimento de procedimentos otimizados de análise sintática para valores numéricos comumente usados em operações de trading.

O gerenciamento de memória torna-se especialmente importante no ambiente MQL5, que possui suas próprias limitações e características específicas. A plataforma MetaTrader opera com recursos limitados, e o uso ineficiente da memória pode afetar o desempenho de todo o sistema de trading. Uma implementação configurável permite ajustar com precisão a alocação e a liberação de memória conforme as necessidades específicas das operações de trading.

Podemos implementar estratégias complexas de cache que reconhecem a localidade temporal das operações de trading. Por exemplo, durante sessões de alta frequência, determinados pares de moedas ou tipos de ordens podem ser reutilizados. Ao armazenar em cache estados intermediários de hash para esses padrões recorrentes, conseguimos reduzir o custo computacional das operações subsequentes.


Perspectiva: garantindo a viabilidade a longo prazo

O mercado de criptomoedas é especialmente dinâmico, e as bolsas frequentemente atualizam seus requisitos e protocolos de segurança. Uma implementação personalizada de SHA-256 fornece a flexibilidade necessária para se adaptar a essas mudanças, mantendo a confiabilidade do sistema.

Considere o fato de que as bolsas podem, ao longo do tempo, alterar seus requisitos de assinatura. Elas podem:

  • Modificar a ordem dos parâmetros na string de assinatura
  • Adicionar novos campos obrigatórios à assinatura
  • Alterar a forma de tratamento de determinados caracteres ou casos especiais
  • Implementar novas medidas de segurança que afetem o método de geração das assinaturas

Graças à implementação personalizada, a adaptação a essas mudanças torna-se simples. Temos controle total sobre cada aspecto do processo de hash, desde o pré-processamento dos dados de entrada até o formato final da saída. Esse nível de controle nos permite reagir rapidamente a novos requisitos, sem depender de atualizações das funções internas do MQL5.

Por exemplo, se uma bolsa decidir alterar a forma de tratamento de caracteres Unicode nas assinaturas, podemos atualizar imediatamente nossa implementação para atender aos novos requisitos. Esse grau de adaptabilidade torna-se essencial ao lidar com múltiplas bolsas, cada uma potencialmente apresentando exigências diferentes.

A independência em relação às funções internas do MQL5 oferece outra vantagem significativa. À medida que a plataforma MetaTrader evolui e recebe atualizações, suas funções internas podem sofrer pequenas alterações que impactam a geração de assinaturas. Uma implementação personalizada permanece estável em diferentes versões do MetaTrader, garantindo um comportamento consistente independentemente das atualizações da plataforma.

O aspecto de segurança voltado para o futuro vai além dos simples requisitos de assinatura. As bolsas de criptomoedas podem introduzir novas funcionalidades de segurança ou métodos de autenticação baseados em SHA-256. Ter uma implementação personalizada nos permite:

  • Expandir a funcionalidade básica do SHA-256 para oferecer suporte a novos recursos de segurança
  • Modificar a implementação para operar com novos esquemas de autenticação
  • Integrar facilmente operações criptográficas adicionais
  • Manter compatibilidade retroativa enquanto adicionamos novas capacidades

Além disso, a implementação personalizada fornece a base para o desenvolvimento de outras funções criptográficas que possam ser necessárias futuramente. A estrutura do código e os métodos de otimização criados para o SHA-256 podem servir de modelo para a implementação de outras funções de hash ou operações criptográficas.

Considere um cenário em que uma bolsa introduz um novo requisito de duplo hash ou uma combinação de SHA-256 com outro algoritmo. Com uma implementação personalizada, adicionar essas funcionalidades torna-se uma questão de expandir o código existente, em vez de tentar contornar as limitações das funções internas.

Essa capacidade de expansão é especialmente valiosa no contexto do mercado de criptomoedas, que evolui rapidamente. Novos padrões de trading, exigências de segurança e avanços tecnológicos podem surgir a qualquer momento, e possuir uma implementação flexível e configurável permite que os sistemas de trading se adaptem e evoluam junto com o mercado.

A combinação de otimização de desempenho e visão de longo prazo torna a implementação personalizada do SHA-256 indispensável para operações sérias de trading de criptomoedas. Ela oferece o controle, a flexibilidade e a eficiência necessários para manter vantagens competitivas em um mercado em constante mudança, assegurando ao mesmo tempo a viabilidade de longo prazo à medida que os requisitos evoluem.


Compreendendo o algoritmo SHA-256

SHA-256 significa algoritmo de hash seguro de 256 bits, sendo uma função de hash criptográfica que recebe dados de entrada arbitrários e gera uma saída de 256 bits (32 bytes) de tamanho fixo.  Ele pertence à família de algoritmos SHA-2 e executa um conjunto de etapas muito sistemático e claramente definido em seu processo — uma característica que equilibra tanto a segurança quanto o determinismo.

Implementação em MQL5

Vamos examinar detalhadamente cada componente. A implementação completa está disponível na seção final para consulta.  Nesta implementação, teremos duas classes, semelhantes àquelas usadas na versão em Python, onde são utilizados os módulos HMAC e SHA256:

A seguir está a estrutura das classes SHA256 e HMAC.

class CSha256Class
  {
private:

   uint              total_message[];
   uint              paddedMessage[64];
   void              Initialize_H();//This function initializes the values of h0-h7
   uint              RawMessage[];//Keeps track of the raw message sent in
public:
   //hash values from h0 - h7
   uint              h0;
   uint              h1;
   uint              h2;
   uint              h3;
   uint              h4;
   uint              h5;
   uint              h6;
   uint              h7;

   uint              K[64];
   uint              W[64];

                     CSha256Class(void);
                    ~CSha256Class() {};

   void              PreProcessMessage(uint &message[], int messageLength);
   void              CreateMessageSchedule();
   void              Compression();
   void              UpdateHash(uint &message[], int message_len);
   void              GetDigest(uint &digest[]);
   string            GetHex();
  };
class HMacSha256
  {
private:

public:
   uint              k_ipad[64];
   uint              k_opad[64];
   uint              K[];
   string            hexval;
                     HMacSha256(string key, string message);
                    ~HMacSha256() {};
   CSha256Class      myshaclass;
   void              ProcessKey(string key);
  };



Guia passo a passo para a implementação dessas classes

Este módulo implementa o algoritmo HMAC, conforme descrito no  RFC 2104.

Passo 1:
Criação da função de processamento da chave. 

void HMacSha256::ProcessKey(string key)
  {
   int keyLength = StringLen(key);//stores the length of the key

   if(keyLength>64)
     {
      uchar keyCharacters[];

      StringToCharArray(key, keyCharacters);
      uint KeyCharuint[];
      ArrayResize(KeyCharuint, keyLength);

      //Converts the keys to their characters
      for(int i=0;i<keyLength;i++)
         KeyCharuint[i] = (uint)keyCharacters[i];

      //Time to hash the 
      CSha256Class keyhasher;
      keyhasher.UpdateHash(KeyCharuint, keyLength);

      uint digestValue[];
      keyhasher.GetDigest(digestValue);
      ArrayResize(K, 64);

      for(int i=0;i<ArraySize(digestValue);i++)
         K[i] = digestValue[i];

      for(int i=ArraySize(digestValue);i<64;i++)
         K[i] = 0x00;

     }
   else
     {
      uchar keyCharacters[];

      StringToCharArray(key, keyCharacters);
      ArrayResize(K, 64);

      for(int i=0;i<keyLength;i++)
         K[i] = (uint)keyCharacters[i];

      for(int i=keyLength;i<64;i++)
         K[i] = 0x00;
     }
  }

Esta implementação leva em conta o comprimento da chave. Se ele for superior a 64, a chave é primeiro processada por meio de hash utilizando nossa classe CSha256Class.

Passo 2:
Implementação completa do HMAC.

HMacSha256::HMacSha256(string key,string message)
  {
//process key and add zeros to complete n bytes of 64
   ProcessKey(key);

   for(int i=0;i<64;i++)
     {
      uint keyval = K[i];
      k_ipad[i] = 0x36 ^ keyval;
      k_opad[i] = 0x5c ^ keyval;
     }

//text chars
   uchar messageCharacters[];
   StringToCharArray(message, messageCharacters);
   int innerPaddingLength = 64+StringLen(message);

   uint innerPadding[];
   ArrayResize(innerPadding, innerPaddingLength);
        
   for(int i=0;i<64;i++)
      innerPadding[i] = k_ipad[i];

   int msg_counts = 0;
   for(int i=64;i<innerPaddingLength;i++)
     {
      innerPadding[i] = (uint)messageCharacters[msg_counts];
      msg_counts +=1;
     }

//send inner padding for hashing
   CSha256Class innerpaddHasher;
   innerpaddHasher.UpdateHash(innerPadding, ArraySize(innerPadding));


   uint ipad_digest_result[];
   innerpaddHasher.GetDigest(ipad_digest_result);

//   merge digest with outer padding
   uint outerpadding[];
   int outerpaddSize = 64 + ArraySize(ipad_digest_result);

   ArrayResize(outerpadding, outerpaddSize);
   for(int i=0;i<64;i++)
      outerpadding[i] = k_opad[i];

   int inner_counts = 0;
   for(int i=64;i<outerpaddSize;i++)
     {
      outerpadding[i] = ipad_digest_result[inner_counts];
      inner_counts+=1;
     }

   CSha256Class outerpaddHash;
   outerpaddHash.UpdateHash(outerpadding, ArraySize(outerpadding));
   hexval = outerpaddHash.GetHex();
  }

Outras funções estão disponíveis no código completo anexado.

O componente central dessa implementação é a função de hash, que é tratada pela classe CSHa256Class.

A função de hash envolve várias etapas de manipulação do texto.

Passo 1: Pré-processamento dos valores.

Precisamos garantir que todos os dados tenham tamanho múltiplo de 512 bits, portanto, aplicamos algumas operações de preenchimento.

  1. Convertendo a mensagem em sua forma binária.
  2. Adicionamos 1 ao final.
  3. Adicionamos zeros como preenchimento até que o comprimento dos dados atinja 448 bits (ou seja, de 512 menos 64 bits). Isso garante que no bloco de 512 bits restem exatamente 64 bits. Em outras palavras, completamos a mensagem de modo que ela satisfaça o requisito de 448 módulo 512.
  4. Adicionamos 64 bits no final, sendo esses 64 bits um número inteiro em ordem reversa de bytes, representando o comprimento original dos dados de entrada em formato binário.

Passo 2: Inicialização dos valores de hash.

Passo 3: Inicialização de constantes redondas.

Passo 4: Dividimos o total de bits da mensagem em blocos de 512 bits e executamos a seguinte operação para cada bloco, de forma iterativa.

   int chunks_count = (int)MathFloor(ArraySize(total_message)/64.0);
   int copied = 0;

   for(int i=0; i<chunks_count; i++)
     {
      uint newChunk[];
      ArrayResize(newChunk, 64);
      ArrayInitialize(newChunk, 0);  // Initialize chunk array

      for(int j=0; j<64; j++)
        {
         newChunk[j] = total_message[copied];
         copied += 1;
        }

      PreProcessMessage(newChunk, ArraySize(newChunk));
      CreateMessageSchedule();
      Compression();
     }

Passo 5: Realizamos o pré-processamento da mensagem, copiando o array de blocos para um novo array, onde cada elemento representa uma palavra de 32 bits.

void CSha256Class::PreProcessMessage(uint &message[],int messageLength)
  {
   ArrayInitialize(paddedMessage, 0);
   for(int i=0; i < messageLength; i++)
      paddedMessage[i] = message[i];
  }
Passo 6: Criamos o agendamento de distribuição das mensagens para o bloco atual.
void CSha256Class::CreateMessageSchedule()
  {
   ArrayInitialize(W, 0);

   int counts = 0;
   for(int i=0; i<ArraySize(paddedMessage); i+=4)
     {
      //32 bits is equivalent to 4 bytes from message
      uint byte1 = paddedMessage[i];
      uint byte2 = paddedMessage[i+1];
      uint byte3 = paddedMessage[i+2];
      uint byte4 = paddedMessage[i+3];

      uint combined = ((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4);
      W[counts] = combined & 0xFFFFFFFF;

      counts += 1;
     }
   for(int i=counts; i<64; i++)
      W[i] = 0x00000000;
//preserve previous counts

   int prev_counts = counts;
   int left_count = 64-counts;
   for(int i=counts; i<64; i++)
     {
      uint s0 = (RightRotate(W[i-15], 7)) ^ (RightRotate(W[i-15],18)) ^ (W[i-15] >> 3);
      uint s1 = (RightRotate(W[i-2], 17)) ^ (RightRotate(W[i-2],19)) ^ (W[i-2] >> 10);

      W[i] = (W[i-16] + s0 + W[i-7] + s1) & 0xFFFFFFFF;
     }
  }

Passo 7:   Aplicamos o ciclo de compressão.

void CSha256Class::Compression(void)
  {
   uint a = h0;
   uint b = h1;
   uint c = h2;
   uint d = h3;
   uint e = h4;
   uint f = h5;
   uint g = h6;
   uint h = h7;

   for(int i=0; i<64; i++)
     {
      uint S1 = (RightRotate(e, 6) ^ RightRotate(e,11) ^ RightRotate(e,25)) & 0xFFFFFFFF;
      uint ch = ((e & f) ^ ((~e) & g))& 0xFFFFFFFF;
      uint temp1 = (h + S1 + ch + K[i] + W[i]) & 0xFFFFFFFF;
      uint S0 = (RightRotate(a, 2) ^ RightRotate(a, 13) ^ RightRotate(a, 22)) & 0xFFFFFFFF;
      uint maj = ((a & b) ^ (a & c) ^ (b & c)) & 0xFFFFFFFF;
      uint temp2 = (S0 + maj) & 0xFFFFFFFF;
      h = g & 0xFFFFFFFF;
      g = f & 0xFFFFFFFF;
      f = e & 0xFFFFFFFF;
      e = (d + temp1) & 0xFFFFFFFF;
      d = c & 0xFFFFFFFF;
      c = b & 0xFFFFFFFF;
      b = a & 0xFFFFFFFF;
      a = (temp1 + temp2)&0xFFFFFFFF;
     }

   h0 = h0 + a;
   h1 = h1 + b;
   h2 = h2 + c;
   h3 = h3 + d;
   h4 = h4 + e;
   h5 = h5 + f;
   h6 = h6 + g;
   h7 = h7 + h;

  }

Após a conclusão do ciclo de compressão, atualizamos os valores finais do hash, somando as variáveis de trabalho modificadas aos valores de hash originais. 
Essa operação de soma é executada após o processamento de cada bloco de 512 bits da mensagem, e os valores de hash atualizados tornam-se o ponto de partida para o processamento do próximo bloco. Esse mecanismo encadeado garante que o hash de cada bloco dependa de todos os blocos anteriores, tornando o valor final do hash dependente de toda a mensagem.


Como utilizar esta classe

Para gerar assinaturas de API tanto para a Binance quanto para a Bybit, criamos uma instância de HMAC (código de autenticação de mensagens baseado em função hash), semelhante à implementação em Python.

void OnStart()
{
   // The text to hash
   string text = "Hello";
   string key_text = "key";   
     
  HMacSha256 sha256(key_text, text);
  Print(sha256.hexval);
}

>>> C70B9F4D665BD62974AFC83582DE810E72A41A58DB82C538A9D734C9266D321E

Ao comparar as assinaturas geradas por ambas as implementações, você verá que elas produzem resultados idênticos.


Considerações finais

Os traders que trabalham com criptomoedas frequentemente enfrentam problemas de compatibilidade de assinaturas de API, otimização de desempenho e sustentabilidade ao utilizar funções criptográficas internas em sistemas de trading como o MetaTrader 5. A partir deste artigo, os traders aprendem a implementar o SHA-256 do zero em MQL5, a fim de superar esses desafios.

Em conclusão, a criação de uma implementação personalizada de SHA-256 oferece aos traders compatibilidade com as bolsas, maior eficiência e flexibilidade para se adaptar a mudanças futuras, tornando-se uma estratégia essencial para operações de trading de criptomoedas seguras e eficazes.

É importante testar regularmente a implementação com base em vetores de teste padrão e verificar as assinaturas junto às bolsas de destino antes de implantá-la em ambiente de produção. À medida que as bolsas de criptomoedas aumentam suas exigências de segurança, dispor de uma implementação flexível e configurável torna-se inestimável para garantir rápida adaptação e manutenção.

Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/16357

Arquivos anexados |
Sha256Algorithm.mqh (18.56 KB)
Sha256TestFile.mq5 (0.89 KB)
Últimos Comentários | Ir para discussão (6)
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 27 fev. 2025 em 14:08
Sergey Zhilinskiy #:

Se o key_text tiver mais de 64 caracteres, o HMacSha256 fará o cálculo incorretamente. O que deve ser corrigido nesse caso?

Minha implementação atual se adapta a chaves com mais de 64 caracteres. Você tem algum par específico de chave e mensagem para o qual ele não funcionou?

Sergey Zhilinskiy
Sergey Zhilinskiy | 27 fev. 2025 em 15:32
Abdulkudus Okatengwu Kadir #:

Minha implementação atual se adapta a chaves com mais de 64 caracteres. Você tem algum par específico de chave e mensagem para o qual isso não funcionou?

string text = "Hello";

string key_text = "1234567890123456789012345678901234567890123456789012345678901234";

https://www.devglan.com/online-tools/hmac-sha256-online -> 7558a77ff19ed6cb4777355e4bbc4772759a8130e1bb0913ba62b88411fdbaf8

Script de teste -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

if string key_text = "123456789012345678901234567890123456789012345678901234567890123" - OK
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 28 fev. 2025 em 11:39
Sergey Zhilinskiy #:

string text = "Hello";

string key_text = "1234567890123456789012345678901234567890123456789012345678901234";

https://www.devglan.com/online-tools/hmac-sha256-online -> 7558a77ff19ed6cb4777355e4bbc4772759a8130e1bb0913ba62b88411fdbaf8

Script de teste -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

if string key_text = "123456789012345678901234567890123456789012345678901234567890123" - OK

Acabei de experimentar em meu terminal e obtive o mesmo resultado que a ferramenta de hash on-line:

2025.02.28 12:37:16.468 hashin_example_code (EURUSD,M5) 7558A77FF19ED6CB4777355E4BBC4772759A8130E1BB0913BA62B88411FDBAF8

usando o código abaixo:
void Hash()
{
   // O texto a ser processado em hash
   string text = "Hello";
   string key_text = "1234567890123456789012345678901234567890123456789012345678901234";
   HMacSha256 myhash(key_text, text);
   Print(myhash.hexval);
}
Talvez você queira compartilhar seu código.

Sergey Zhilinskiy
Sergey Zhilinskiy | 1 mar. 2025 em 02:50

Sim, ele funciona corretamente com o Sha256Algorithm.mqh original. Fiz algumas alterações, talvez seja por isso que não funcionou?

 string CSha256Class::GetHex( void )
  {
   string result  = "" ;
 /*
 result += UintToHex(h0);
 result += UintToHex(h1);
 result += UintToHex(h2);
 result += UintToHex(h3);
 result += UintToHex(h4);
 result += UintToHex(h5);
 result += UintToHex(h6);
 result += UintToHex(h7);
*/ 
   result += StringFormat ( "%.2x" ,h0);
   result += StringFormat ( "%.2x" ,h1);
   result += StringFormat ( "%.2x" ,h2);
   result += StringFormat ( "%.2x" ,h3);
   result += StringFormat ( "%.2x" ,h4);
   result += StringFormat ( "%.2x" ,h5);
   result += StringFormat ( "%.2x" ,h6);
   result += StringFormat ( "%.2x" ,h7);

   return (result);
  }

Desculpe-me por incomodá-lo!

Stanislav Korotky
Stanislav Korotky | 2 jul. 2025 em 11:29
Há uma implementação de SHA256, SHA384, SHA512 no kodobase, que também funciona na MQL5.
Estratégia de trading "Captura de Liquidez" (Liquidity Grab) Estratégia de trading "Captura de Liquidez" (Liquidity Grab)
A estratégia de captura de liquidez é um componente-chave do Smart Money Concepts (SMC), que visa identificar e aproveitar as ações dos participantes institucionais no mercado. Ela envolve mirar áreas de alta liquidez, como zonas de suporte ou resistência, onde ordens de grande volume podem provocar um movimento de preço antes que o mercado retome sua tendência. Este artigo explica em detalhes o conceito de captura de liquidez e descreve o processo de desenvolvimento de um EA para a estratégia de captura de liquidez em MQL5.
A Arte de Registrar Logs (Parte 3): Explorando os handlers para armazenamento de logs A Arte de Registrar Logs (Parte 3): Explorando os handlers para armazenamento de logs
Neste artigo, vamos analisar a concepção dos handlers na biblioteca de registro, compreender seu funcionamento e criar três implementações iniciais: console, banco de dados e arquivo. Analisaremos tudo, desde a estrutura básica dos handlers até testes práticos, lançando assim a base para uma implementação completa no futuro.
Dominando Operações de Arquivos em MQL5: Do I/O Básico à Construção de um Leitor CSV Personalizado Dominando Operações de Arquivos em MQL5: Do I/O Básico à Construção de um Leitor CSV Personalizado
Este artigo aborda técnicas essenciais de manipulação de arquivos em MQL5, abrangendo logs de operações, processamento de CSV e integração de dados externos. Ele oferece tanto compreensão conceitual quanto orientação prática de codificação. Os leitores aprenderão a construir uma classe personalizada de importação CSV passo a passo, adquirindo habilidades práticas para aplicações reais.
Integrando MQL5 com pacotes de processamento de dados (Parte 4): Manipulação de Big Data Integrando MQL5 com pacotes de processamento de dados (Parte 4): Manipulação de Big Data
Explorando técnicas avançadas para integrar o MQL5 com ferramentas poderosas de processamento de dados, esta parte se concentra no tratamento eficiente de big data para aprimorar a análise de negociação e a tomada de decisões.