【MQL5】CryptDecode関数について

MQL5リファレンス
スポンサーリンク
スポンサーリンク

CryptDecode関数の働き・役割

CryptDecode関数は、CryptEncode関数で暗号化されたデータを復号化するために使用されます。この関数は、指定された暗号化方式を使って、暗号化された配列から元のデータを逆変換します。CryptEncode関数で使用した暗号化キーと同じキーを使うことで、データを復号化し元の形に戻すことができます。

CryptDecode関数の引数について

CryptDecode関数引数は、以下の通りです。

第1引数: method

methodは、暗号化および復号化の手法を指定します。これはENUM_CRYPT_METHOD列挙型の値の1つを指定します。たとえば、DES暗号化方式やAES 128ビット暗号化方式などがあります。

第2引数: data[]

dataは、暗号化されたソースデータを格納した配列です。この配列には、CryptEncode関数で暗号化されたバイトデータが含まれます。

第3引数: key[]

keyは、暗号化および復号化に使用するキーを格納した配列です。CryptEncode関数で使用したのと同じキーを指定する必要があります。暗号化方式によって、キーの長さやフォーマットが異なります。

第4引数: result[]

resultは、復号化されたデータを格納するための配列です。復号化された後、resultに元のデータが保存されます。この配列のサイズは、必要な容量に応じて適切に確保しておく必要があります。

CryptDecode関数の戻り値について

CryptDecode関数は、復号化されたデータのバイト数を整数として返します。成功した場合、復号化されたデータのサイズ(バイト数)が返されます。エラーが発生した場合は0が返され、エラーの詳細はGetLastError関数を使用して取得することができます。

例えば、復号化に失敗した場合には、原因を確認するためにGetLastError関数を呼び出すことが推奨されます。

CryptDecode関数を使ったサンプルコード

//+------------------------------------------------------------------+
//| ArrayToHex                                                       |
//| バイト配列を16進数形式の文字列に変換する関数                                 |
//+------------------------------------------------------------------+
string ArrayToHex(uchar &arr[], int count=-1)
 {
  string res=""; // 結果の文字列を初期化
//--- 配列サイズが適切かチェック
  if(count<0 || count>ArraySize(arr))
     count=ArraySize(arr); // カウントが不正の場合は配列のサイズに設定
//--- 配列を16進数文字列に変換
  for(int i=0; i<count; i++)
     res+=StringFormat("%.2X",arr[i]); // 各バイトを16進数形式で文字列に追加
//--- 結果の文字列を返す
  return(res);
 }

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                          |
//| OnStart関数は、スクリプト実行時に呼び出される自動的なエントリーポイントです   |
//+------------------------------------------------------------------+
void OnStart()
 {
  string text="The quick brown fox jumps over the lazy dog"; // 暗号化する元のテキスト
  string keystr="ABCDEFG"; // 暗号化に使用するキー
  uchar src[], dst[], key[]; // データ配列(src: 元データ, dst: 暗号化されたデータ, key: 暗号化キー)
//--- キーを準備する(文字列をバイト配列に変換)
  StringToCharArray(keystr, key);
//--- テキストをsrc配列に変換する(文字列をバイト配列にコピー)
  StringToCharArray(text, src);
//--- 初期データの情報を出力する
  PrintFormat("Initial data: size=%d, string='%s'", ArraySize(src), CharArrayToString(src)); 
  // 配列サイズと文字列としての内容を出力
//--- src配列をkey配列を使ってDES 56ビットキーで暗号化
  int res = CryptEncode(CRYPT_DES, src, key, dst); 
  // CRYPT_DES方式で暗号化を実行し、結果をdst配列に格納

//--- 暗号化処理が成功したか確認
  if(res > 0)
    {
    //--- 暗号化されたデータを16進数形式で表示
    PrintFormat("Encoded data: size=%d %s", res, ArrayToHex(dst)); 
    // 暗号化後のデータサイズと16進数形式の内容を出力
    //--- 暗号化されたdst配列をsrc配列にデコードする
     res = CryptDecode(CRYPT_DES, dst, key, src); 
     // 同じキーとDES方式でデコードを実行

    //--- デコードが成功したか確認
    if(res > 0)
       {
        //--- デコードされたデータを表示
        PrintFormat("Decoded data: size=%d, string='%s'", ArraySize(src), CharArrayToString(src)); 
        // デコードされたデータのサイズと文字列を出力
       }
    else
        Print("Error in CryptDecode. Error code=", GetLastError()); 
        // デコードエラーが発生した場合のエラーメッセージを出力
    }
  else
    Print("Error in CryptEncode. Error code=", GetLastError()); 
    // 暗号化エラーが発生した場合のエラーメッセージを出力
 }

サンプルコード解説1:ArrayToHex関数(オリジナル関数)

//+------------------------------------------------------------------+
//| ArrayToHex                                                       |
//| バイト配列を16進数形式の文字列に変換する関数                                 |
//+------------------------------------------------------------------+
string ArrayToHex(uchar &arr[], int count=-1)
 {
  string res=""; // 結果の文字列を初期化
//--- 配列サイズが適切かチェック
  if(count<0 || count>ArraySize(arr))
     count=ArraySize(arr); // カウントが不正の場合は配列のサイズに設定
//--- 配列を16進数文字列に変換
  for(int i=0; i<count; i++)
     res+=StringFormat("%.2X",arr[i]); // 各バイトを16進数形式で文字列に追加
//--- 結果の文字列を返す
  return(res);
 }

ArrayToHex関数は、uchar型配列16進数形式の文字列に変換するためのカスタム関数です。MQL5では、データをバイト配列で扱うことが多く、暗号化処理後の結果やバイナリデータを人間が読みやすい形式に変換するために使用されます。この関数は特に、暗号化されたデータを16進数表記で確認したい場合に役立ちます。

1. 引数の解説

  • 第1引数: uchar &arr[]
    この引数は、変換対象のバイト配列です。uchar型は符号なし8ビット整数であり、バイト単位のデータを格納します。この配列の中身が、16進数形式に変換されます。
  • 第2引数: int count=-1
    countは、変換するバイト数を指定する引数です。デフォルト値は-1で、特に指定がない場合には、配列のサイズ全体を変換対象とします。この引数に正の数値を渡すと、そのバイト数だけが変換されます。

2. 処理の流れ

3. 使用場面

この関数は、暗号化やバイナリデータの取り扱い時に役立ちます。例えば、暗号化後のデータをログに出力する際に、この関数を使用して16進数形式に変換することで、データの内容を可視化できます。また、暗号化の正当性を検証する場合にも、元のデータと暗号化されたデータを比較する際に利用されます。

サンプルコード解説2:OnStart関数その1

//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                          |
//| OnStart関数は、スクリプト実行時に呼び出される自動的なエントリーポイントです   |
//+------------------------------------------------------------------+
void OnStart()
 {
  string text="The quick brown fox jumps over the lazy dog"; // 暗号化する元のテキスト
  string keystr="ABCDEFG"; // 暗号化に使用するキー
  uchar src[], dst[], key[]; // データ配列(src: 元データ, dst: 暗号化されたデータ, key: 暗号化キー)

OnStart関数は、スクリプトが実行される際に最初に呼び出される関数であり、スクリプトのエントリーポイントとなります。この関数では、暗号化と復号(暗号化されたデータを元のデータに戻すこと)のための準備が行われます。以下は、その一部についての詳細な解説です。

1. 暗号化するテキストとキーの準備

  • text変数
    この変数には、暗号化対象の文字列が格納されています。この例では、”The quick brown fox jumps over the lazy dog” というテキストを暗号化します。このテキストは、暗号化の処理対象として配列に変換されます。
  • keystr変数
    暗号化に使用するキーを保持する文字列変数です。この例では、”ABCDEFG” という簡単な文字列がキーとして使用されています。暗号化アルゴリズムによっては、キーの長さや内容が暗号の強度に影響を与えるため、実際の用途では適切な長さと内容のキーを選ぶ必要があります。

2. 配列の初期化

これらの準備により、暗号化および復号のプロセスが開始される前段階が整えられます。

サンプルコード解説3:OnStart関数その2

  StringToCharArray(keystr, key);
//--- テキストをsrc配列に変換する(文字列をバイト配列にコピー)
  StringToCharArray(text, src);
//--- 初期データの情報を出力する
  PrintFormat("Initial data: size=%d, string='%s'", ArraySize(src), CharArrayToString(src)); 
  // 配列サイズと文字列としての内容を出力
//--- src配列をkey配列を使ってDES 56ビットキーで暗号化
  int res = CryptEncode(CRYPT_DES, src, key, dst); 
  // CRYPT_DES方式で暗号化を実行し、結果をdst配列に格納

この部分では、文字列データをバイト配列に変換し、暗号化処理を実行しています。

1. 文字列をバイト配列に変換

  • StringToCharArray関数によるキーの準備
    StringToCharArray(keystr, key) によって、キー文字列 “ABCDEFG” がバイト配列である key に変換されます。これにより、暗号化処理に使用できる形式のキーが用意されます。
  • テキストをバイト配列に変換
    次に、StringToCharArray(text, src) を使って、暗号化対象のテキスト “The quick brown fox jumps over the lazy dog” が src 配列に変換されます。この配列は、暗号化の入力データとなります。

2. 初期データの出力

3. 暗号化の実行

  • CryptEncode関数による暗号化
    CryptEncode(CRYPT_DES, src, key, dst) では、DES(データ暗号化標準)方式を使用して、src 配列のデータを key 配列のキーで暗号化し、その結果を dst 配列に格納します。DESは56ビットのキーを使用した古典的な暗号化アルゴリズムで、暗号化の結果がバイト配列dst に保存されます。

サンプルコード解説4:OnStart関数その3

//--- 暗号化処理が成功したか確認
  if(res > 0)
    {
    //--- 暗号化されたデータを16進数形式で表示
    PrintFormat("Encoded data: size=%d %s", res, ArrayToHex(dst)); 
    // 暗号化後のデータサイズと16進数形式の内容を出力
    //--- 暗号化されたdst配列をsrc配列にデコードする
     res = CryptDecode(CRYPT_DES, dst, key, src); 
     // 同じキーとDES方式でデコードを実行

    //--- デコードが成功したか確認
    if(res > 0)
       {
        //--- デコードされたデータを表示
        PrintFormat("Decoded data: size=%d, string='%s'", ArraySize(src), CharArrayToString(src)); 
        // デコードされたデータのサイズと文字列を出力
       }
    else
        Print("Error in CryptDecode. Error code=", GetLastError()); 
        // デコードエラーが発生した場合のエラーメッセージを出力
    }

このセクションでは、暗号化と復号(デコード)処理の結果を確認し、エラー処理を行う部分を解説します。

1. 暗号化処理の結果確認

  • 暗号化が成功したかの確認
    res > 0 の条件で、暗号化が正常に行われたかを確認します。このresは、CryptEncode関数戻り値であり、暗号化が成功した場合には暗号化後のデータサイズ(バイト数)が返されます。成功していれば、そのサイズを基に次の処理に進みます。
  • 暗号化されたデータの表示
    PrintFormat関数を使用して、暗号化されたデータのサイズと、その内容を16進数形式で出力します。ArrayToHex関数を使用してバイト配列16進数形式に変換し、暗号化された内容を視覚的に確認できるようにしています。

2. 暗号化データの復号(デコード)

  • CryptDecode関数による復号
    CryptDecode(CRYPT_DES, dst, key, src) では、DES方式を使用して、暗号化されたdst配列のデータをsrc配列に復号します。この際、暗号化に使用したのと同じキーでデコードを実行します。デコードによって、元のテキストデータがsrc配列に復元されます。

3. 復号処理の結果確認

  • デコードが成功したかの確認
    res > 0 でデコードが成功したかをチェックします。デコードが成功すると、デコード後のデータサイズが戻り値として返されます。
  • デコードされたデータの表示
    デコードが成功した場合、PrintFormat関数を使って復号されたデータを表示します。ArraySize(src) で復号後の配列サイズを取得し、CharArrayToString(src) でバイト配列を再び文字列に変換して出力します。これにより、元の文字列が正しく復元されたことが確認できます。

4. エラー処理

  • エラーメッセージの表示
    デコードに失敗した場合は、Print関数を使用してエラーメッセージを表示し、GetLastError関数でエラーコードを取得してエキスパートログに出力します。

サンプルコード解説5:OnStart関数その4

 else
    Print("Error in CryptEncode. Error code=", GetLastError()); 
    // 暗号化エラーが発生した場合のエラーメッセージを出力
 }

この最後の部分では、暗号化が失敗した場合のエラーメッセージ出力と、その処理について説明します。

1. 暗号化エラーの確認

  • 暗号化失敗時の処理
    CryptEncode関数の実行結果を確認した際、戻り値が0以下の場合は暗号化が失敗したことを意味します。その場合、if文elseブロックが実行されます。ここでは、暗号化エラーが発生したことを示すメッセージをエキスパートログに出力します。

2. エラーメッセージの出力

  • Print関数を使用してエラーメッセージを表示
    Print関数を使用して、「Error in CryptEncode」というメッセージと、エラーコードをエキスパートログに出力します。エラーコードは、GetLastError関数を使用して取得されます。このエラーコードによって、何が原因で暗号化が失敗したかを確認できます。エラーコードの内容を調べることで、具体的な問題点を特定し、対応策を講じることができます。
タイトルとURLをコピーしました