English Deutsch 日本語
preview
Реализация криптографического алгоритма SHA-256 с нуля на MQL5

Реализация криптографического алгоритма SHA-256 с нуля на MQL5

MetaTrader 5Примеры |
339 6
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir

Достижения в области MQL5 позволяют эффективно реализовывать криптографические алгоритмы без использования сторонних решений, повышая безопасность, оптимизацию и стабильность. Преимущества пользовательской реализации включают в себя корректировку под конкретные задачи, устранение уязвимостей и постоянную эффективность в разных средах. Криптография теперь является неотъемлемой частью API, проверки транзакций и целостности данных, что требует от разработчиков глубокого понимания этих алгоритмов. Конвергенция криптографии и торговых систем стала обязательным аспектом разработки современных платформ.


Проблемы совместимости сигнатур API

Основной движущей силой для пользовательской реализации SHA-256 является фундаментальная несовместимость встроенных функций хэширования MQL5 и требований к биржам криптовалют. Эта несовместимость проявляется несколькими критическими способами, которые непосредственно влияют на торговые операции.

Когда торговые платформы обращаются по API к криптовалютным биржам, таким как Binance или Bybit, они должны генерировать криптографические сигнатуры, которые идеально соответствуют ожиданиям биржи. Эти сигнатуры служат доказательством подлинности каждого запроса, гарантируя, что ордеры и другие конфиденциальные операции поступают из уполномоченных источников. Однако встроенные криптографические функции на MQL5 часто генерируют сигнатуры, отличающиеся от сигнатур, создаваемых стандартными реализациями на других языках программирования.

Это несоответствие сигнатур возникает из-за того, что криптовалютные биржи обычно ожидают, что сигнатуры будут сгенерированы в соответствии с определенными стандартами, часто основанными на реализациях на таких языках, как Python или JavaScript. Встроенные функции MQL5, хотя и предназначены для общих целей, могут по-разному обрабатывать некоторые аспекты процесса хэширования, такие как:

  1. Упорядочение байтов при обработке входных данных
  2. Реализации дополнений
  3. Обработка кодировки символов
  4. Представление промежуточных значений в памяти
  5. Обработка специальных символов во входной строке

Эти различия приводят к ряду серьезных операционных проблем в производственных средах:

Во-первых, биржи отклоняют запросы API из-за того, что сигнатуры не соответствуют ожидаемым значениям. Это отклонение происходит на уровне аутентификации, еще до того, как начнет выполняться фактическая торговая логика. Рассмотрим сценарий, в котором торговый алгоритм определяет выгодную возможность и пытается разместить ордер. Если сигнатура недействительна, биржа немедленно отклоняет запрос, в результате чего система полностью упускает торговую возможность.

Во-вторых, сбои аутентификации стабильно происходят при различных типах вызовов API. Даже такие простые операции, как получение баланса счета или проверка статуса ордера, становятся невозможными, поскольку биржа не может подтвердить подлинность запроса. Это создает системную проблему, влияющую на каждый аспект работы торговой системы.

В-третьих, размещение ордеров становится особенно проблематичным. При попытке разместить ордера недействительные сигнатуры препятствуют совершению сделок, что может привести к:

  • Пропущенные точки входа для запланированных сделок
  • Невозможность выхода из позиций при необходимости
  • Неудачные операции по управлению рисками
  • Неполное исполнение торговых стратегий

В-четвертых, проверка сообщений становится ненадежной. Многие биржи используют проверку на основе хэша для различных типов сообщений и уведомлений. Несогласованные выходные данные хэша означают, что торговая система не может надежно проверить эти сообщения, потенциально пропуская важные обновления или действуя на основе непроверенной информации.

Последствия этих проблем с совместимостью выходят за рамки непосредственных технических проблем. Они влияют на всю торговую операцию незаметным, но существенным образом:

  • Торговые стратегии не могут быть надежно исполнены
  • Системы управления рисками могут работать не так, как предполагалось
  • Мониторинг системы и ведение лога становятся менее надежными
  • Интеграция с биржевыми API требует постоянных поисков обходных путей

Например, рассмотрим типичный вызов API для криптовалютной биржи. Одни и те же входные данные могут создавать совершенно разные сигнатуры:

Использование встроенной функции на 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
*/

Использование стандартной реализации:


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"

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

Пользовательские реализации SHA-256 предоставляют разработчикам возможность контролировать:

    Приведение в соответствие с конкретными требованиями биржи.
    Адаптирование к меняющимся стандартам.
    Устранение проблем, связанных с сигнатурами.
    Обеспечение согласованности всей торговой системы.

Этот контроль имеет решающее значение для высокочастотной торговли и сложных стратегий, где надежность и скорость имеют первостепенное значение. Несмотря на сложность, индивидуальные решения повышают надежность и интеграцию в производственные торговые системы.

Разница в реализации HMAC и SHA-256

  • Python  использует библиотеку hmac, которая выполняет  HMAC  (код аутентификации (проверки подлинности) сообщений, использующий хеш-функции). Это не просто хэширование текста с помощью ключа, а комбинированный процесс:
    1. Ключ дополняется (или обрезается) до необходимого размера.
    2. Выполняются два этапа хэширования: сначала с ключом и сообщением, затем с ключом и промежуточным результатом.
  • MQL5  в этом коде выполняет только вычисления  SHA-256  с помощью CryptEncode() без полной реализации HMAC. Это обычное хэширование текста с помощью ключа, а не HMAC.

Заключение : Python использует HMAC, в то время как MQL5 использует только SHA-256, что уже гарантирует другие результаты.


Оптимизация эффективности: Глубокое погружение

При реализации SHA-256 в торговую среду оптимизация эффективности приобретает решающее значение, поскольку каждая миллисекунда может повлиять на результаты торговли. Пользовательская реализация предлагает несколько способов оптимизации, которые были бы невозможны при использовании встроенных функций.

Торговые системы часто демонстрируют специфические паттерны в своих криптографических операциях. Например, сигнатуры ордеров обычно содержат аналогичные компоненты, такие как временные метки, символы и количества. Понимая эти паттерны, мы можем оптимизировать нашу реализацию SHA-256 специально для структур данных, связанных с трейдингом.

Рассмотрим, как работает размещение ордеров в типичном торговом сценарии. Для каждого ордера требуется несколько фрагментов информации: торговая пара, тип ордера, количество, цена и временная метка. В стандартных реализациях эти данные каждый раз обрабатывались бы как совершенно новые входные данные. Однако мы можем оптимизировать этот процесс, признавая, что многие компоненты остаются неизменными или следуют предсказуемым паттернам.

Рассмотрим, как эта оптимизация работает на практике. При создании сигнатур для ордеров большая часть структуры данных остается неизменной:

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

В этой строке между ордерами обычно меняются только несколько элементов: количество, цена и временная метка. Структурируя нашу реализацию таким образом, чтобы эффективно обрабатывать эти частичные изменения, можно значительно повысить эффективность. Сюда можно отнести следующее:

  • Создание специализированных функций предварительной обработки, которые эффективно обрабатывают общие структуры торговых данных,
  • Реализация интеллектуального управления буфером для часто используемых компонентов,
  • Разработка оптимизированных процедур синтаксического анализа числовых значений, которые обычно используются в торговых операциях.

Управление памятью становится особенно важным в среде MQL5, которая имеет свои специфические ограничения и признаки. Платформа MetaTrader работает с ограниченными ресурсами и неэффективное использование памяти может повлиять на эффективность всей торговой системы. Настраиваемая реализация позволяет нам точно настраивать распределение и освобождение памяти в зависимости от конкретных потребностей наших торговых операций.

Мы можем реализовать сложные стратегии кэширования, которые распознают временную локальность торговых операций. Например, во время высокочастотных торговых сессий определенные торговые пары или типы ордеров могут использоваться повторно. Кэшируя промежуточные состояния хэша для этих общих паттернов, мы можем сократить вычислительные затраты на последующие операции.


Перспективность: Обеспечение долгосрочной жизнеспособности

Рынок криптовалют особенно динамичен, и биржи часто обновляют свои требования и протоколы безопасности. Пользовательская реализация SHA-256 обеспечивает гибкость, необходимую для адаптации к этим изменениям, сохраняя при этом надежность системы.

Рассмотрим вопрос, как биржи могут со временем изменять свои требования к сигнатурам. Они могут:

  • Изменять порядок следования параметров в строке сигнатур
  • Добавлять новые обязательные поля в сигнатуру
  • Изменять способ обработки определенных символов или особых случаев
  • Внедрять новые меры безопасности, влияющие на способ создания сигнатур

Благодаря пользовательской реализации адаптация к этим изменениям становится простой. Мы полностью контролируем каждый аспект процесса хэширования, от предварительной обработки исходных данных до окончательного форматирования выходных данных. Этот элемент управления позволяет нам быстро реагировать на новые требования, не дожидаясь обновления встроенных функций MQL5.

Например, если биржа решит изменить способ обработки символов Unicode в сигнатурах, мы можем немедленно обновить нашу реализацию, чтобы она соответствовала новым требованиям. Такой уровень адаптивности становится решающим при работе с несколькими биржами, каждая из которых потенциально предъявляет различные требования.

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

Аспект обеспечения безопасности в будущем выходит за рамки простых требований к сигнатуре. Криптовалютные биржи могут внедрять новые функции безопасности или методы аутентификации, основанные на SHA-256. Наличие пользовательской реализации позволяет нам:

  • Расширять базовую функциональность SHA-256 для поддержки новых функций безопасности
  • Изменять реализацию для работы с новыми схемами аутентификации
  • Легко интегрировать дополнительные криптографические операции
  • Поддерживать обратную совместимость, добавляя новые возможности

Кроме того, пользовательская реализация обеспечивает основу для реализации других криптографических функций, которые могут понадобиться в будущем. Структура кода и методы оптимизации, разработанные для SHA-256, могут служить шаблоном для реализации других хэш-функций или криптографических операций.

Рассмотрим сценарий, в котором биржа вводит новое требование к двойному хэшированию или сочетает SHA-256 с другим алгоритмом. При пользовательской реализации добавление этих функций становится вопросом расширения существующего кода, а не попыткой обойти ограничения встроенных функций.

Такая расширяемость особенно ценна в условиях быстро развивающейся торговли криптовалютами. Новые паттерны торговли, требования к безопасности и технологические достижения могут появиться быстро, а наличие гибкой, настраиваемой реализации позволяет торговым системам адаптироваться и развиваться вместе с рынком.

Сочетание оптимизации производительности и перспективных возможностей делает пользовательскую реализацию SHA-256 незаменимой для серьезных операций по торговле криптовалютами. Это обеспечивает контроль, гибкость и эффективность, необходимые для сохранения конкурентных преимуществ на быстро меняющемся рынке, обеспечивая при этом долгосрочную жизнеспособность по мере изменения требований.


Ознакомление с алгоритмом SHA-256

SHA-256  расшифровывается как  256-битный алгоритм безопасного хэширования,  представляющий собой  криптографическую хэш-функцию, принимающую произвольные входные данные  и  отображающую  256-битные (32-байтовые) выходные данные фиксированного размера.  Он  относится к  семейству алгоритмов  SHA-2  и выполняет  очень систематический  и четко  определенный  набор  шагов в  своем процессе -  признак,  который уравновешивает  как  безопасность,  так  и  детерминизм.

Реализация MQL5

Подробно рассмотрим каждый компонент. Полная реализация доступна в последнем разделе для ознакомления.  В этой реализации у нас будет два класса, аналогичных реализации на Python, где используются классы HMAC и SHA256:

Ниже представлена структура класса SHA256 и 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);
  };



Пошаговое руководство по реализации этих классов

Этот модуль реализует алгоритм HMAC, описанный в  RFC 2104.

Шаг 1:
Создание функции для обработки ключа. 

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

Эта реализация учитывает длину ключа, если она больше 64, то сначала ее хэшируют с помощью нашего класса CSha256Class.

Шаг 2:
Полная реализация 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();
  }

Другие функции доступны в прилагаемом полном коде.

Ключевым компонентом этой реализации является хэш-функция, которая обрабатывается классом CSHa256Class.

Функция хеширования включает в себя несколько этапов работы с текстом.

Шаг 1: Предварительная обработка значений.

Нам нужно убедиться, что все данные кратны 512 битам, поэтому мы применяем некоторые операции заполнения.

  1. Преобразуем сообщение в его двоичную форму.
  2. Добавим 1 в конец.
  3. Добавим нули в качестве заполнения до тех пор, пока длина данных не достигнет 448 бит (что составляет от 512 до 64 бит). Это гарантирует, что в 512-битном блоке останется ровно 64 бита. Другими словами, мы дополняем сообщение так, чтобы оно соответствовало 448 по модулю 512.
  4. Добавим 64 бита в конец, где 64 бита - это целое число  с обратным порядком данных , представляющее длину исходных входных данных в двоичном формате.

Шаг 2: Инициализация хэш-значений.

Шаг 3: Инициализация круглых констант.

Шаг 4: Разделите общее количество битов сообщения на 512 бит в каждом блоке и выполните следующую операцию с каждым блоком итеративно.

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

Шаг 5: Выполним предварительную обработку сообщения, скопировав массив блоков в новый массив, где каждая запись представляет собой 32-разрядное слово.

void CSha256Class::PreProcessMessage(uint &message[],int messageLength)
  {
   ArrayInitialize(paddedMessage, 0);
   for(int i=0; i < messageLength; i++)
      paddedMessage[i] = message[i];
  }
Шаг 6: Создадим расписание рассылки сообщений для этого блока.
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;
     }
  }

Шаг 7:   Применим цикл сжатия.

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;

  }

После завершения цикла сжатия обновляем конечные значения хэша, добавляя измененные рабочие переменные к исходным значениям хэша. 
Эта операция добавления выполняется после обработки каждого 512-битного блока сообщения, и обновленные значения хэша становятся начальной точкой для обработки следующего блока. Этот цепочный механизм обеспечивает, что хэш каждого блока зависит от всех предыдущих блоков, что делает конечное значение хэша зависимым от всего сообщения.


Как пользоваться этим классом

Чтобы сгенерировать сигнатуры API как для Binance, так и для Bybit, создадим экземпляр HMAC (код аутентификации (проверки подлинности) сообщений, использующий хеш-функции), аналогичный реализации на Python.

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

>>> C70B9F4D665BD62974AFC83582DE810E72A41A58DB82C538A9D734C9266D321E

Сравнив сигнатуры, сгенерированные обеими реализациями, вы увидите, что они дают идентичные результаты.


Заключение

Работающие с криптовалютами трейдеры часто сталкиваются с проблемами совместимости сигнатур API, оптимизации эффективности и перспективности при использовании встроенных криптографических функций в таких торговых системах, как MetaTrader 5. Из настоящей статьи трейдеры узнают, как реализовать SHA-256 с нуля в MQL5, чтобы преодолеть эти проблемы.

В заключение, создание пользовательской реализации SHA-256 обеспечивает трейдерам совместимость с биржами, повышенную эффективность и гибкость для адаптации к будущим изменениям, что делает ее важной стратегией для безопасных и эффективных торговых операций с криптовалютами.

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

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/16357

Прикрепленные файлы |
Sha256Algorithm.mqh (18.56 KB)
Sha256TestFile.mq5 (0.89 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (6)
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 27 февр. 2025 в 14:08
Sergey Zhilinskiy #:

Если текст_ключа превышает 64 символа, то HMacSha256 вычисляется некорректно. Что следует исправить в этом случае?

Моя текущая реализация адаптируется к ключам длиной более 64 символов. Есть ли у вас конкретная пара ключ-сообщение, для которой она не работает?

Sergey Zhilinskiy
Sergey Zhilinskiy | 27 февр. 2025 в 15:32
Abdulkudus Okatengwu Kadir #:

Моя текущая реализация адаптируется к ключам длиной более 64 символов. Есть ли у вас конкретная пара ключ-сообщение, для которой она не работает?

string text = "Hello";

string key_text = "1234567890123456789012345678901234567890123456789012345678901234";

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

Тестовый скрипт -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

если string key_text = "123456789012345678901234567890123456789012345678901234567890123" - OK
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 28 февр. 2025 в 11:39
Sergey Zhilinskiy #:

string text = "Привет";

string key_text = "1234567890123456789012345678901234567890123456789012345678901234";

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

Тестовый скрипт -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

если string key_text = "123456789012345678901234567890123456789012345678901234567890123" - OK

Я только что попробовал это на своем терминале и получил то же самое, что и онлайн хэш-инструмент:

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

используя код ниже:
.
void Hash()
{
   // Текст для хэширования
   string text = "Hello";
   string key_text = "1234567890123456789012345678901234567890123456789012345678901234";
   HMacSha256 myhash(key_text, text);
   Print(myhash.hexval);
}
Возможно, вы захотите поделиться своим кодом.

Sergey Zhilinskiy
Sergey Zhilinskiy | 1 мар. 2025 в 02:50

Да, он работает правильно с оригинальным Sha256Algorithm.mqh. Я внес некоторые изменения, может быть, поэтому он не работает?

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

Извините за беспокойство!

Stanislav Korotky
Stanislav Korotky | 2 июл. 2025 в 11:29
Есть реализация SHA256, SHA384, SHA512 в кодобазе, работает и в MQL5.
Индикатор сезонности по часам, дням недели и месяца Индикатор сезонности по часам, дням недели и месяца
Статья объясняет, как разработать инструмент для анализа повторяющихся ценовых закономерностей на финансовых рынках — по дням месяца (1-31), дням недели (понедельник-воскресенье) или часам дня (0-23). Индикатор анализирует исторические данные, вычисляет среднюю доходность для каждого периода и отображает результаты в виде гистограммы с прогнозом. Включает настраиваемые параметры: тип сезонности, количество анализируемых баров, отображение в процентах или абсолютных значениях, цвета графиков.
Искусство ведения логов (Часть 1): Основные понятия и первые шаги в MQL5 Искусство ведения логов (Часть 1): Основные понятия и первые шаги в MQL5
Добро пожаловать в новое приключение! Данная статья открывает специальный цикл, в котором мы будем пошагово создавать библиотеку для манипуляций с журналами, предназначенную для тех, кто занимается разработкой на языке MQL5.
Возможности Мастера MQL5, которые вам нужно знать (Часть 47): Обучение с подкреплением (алгоритм временных различий) Возможности Мастера MQL5, которые вам нужно знать (Часть 47): Обучение с подкреплением (алгоритм временных различий)
Temporal Difference (TD, временные различия) — еще один алгоритм обучения с подкреплением, который обновляет Q-значения на основе разницы между прогнозируемыми и фактическими вознаграждениями во время обучения агента. Особое внимание уделяется обновлению Q-значений без учета их пар "состояние-действие" (state-action). Как обычно, мы рассмотрим, как этот алгоритм можно применить в советнике, собранном с помощью Мастера.
Нейросети в трейдинге: Адаптивная периодическая сегментация (Окончание) Нейросети в трейдинге: Адаптивная периодическая сегментация (Окончание)
Предлагаем погрузиться в захватывающий мир LightGTS — лёгкого, но мощного фреймворка для прогноза временных рядов, где адаптивная свёртка и RoPE‑кодирование сочетаются с инновационным методами внимания. В нашей статье вы найдёте детальное описание всех компонентов — от создания патчей до сложной смеси экспертов в декодере, готовых к интеграции в MQL5‑проекты. Откройте для себя, как LightGTS выводит автоматическую торговлю на новый уровень!