CryptDecode with modifier CRYPT_ARCH_ZIP - How to use? - ページ 10

 

バシリー!

あなたからの返事を待たずに。(MQがビルド1100で変更を実装する時間があったかどうかは分かりませんが)

デコーダーです。

//+------------------------------------------------------------------+
//|                                                  Zip_decoder.mq5 |
//|                                          Copyright 2015, Mikalas |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//
#define uint_size  4
#define hdr_size   2
#define descr_size 12
//
struct ZIP_HEADER
{
  uint   sign;
  ushort a_version;
  ushort bit_flag;
  ushort comp_method;
  ushort last_mod_time;
  ushort last_mod_date;
  uint   crc_32;
  uint   pack_size;
  uint   unpack_size;
  ushort fn_len;
  ushort extr_field_len;
};
//---
struct ZIP_ENTRYES
{
  uint   file_count;
  string zip_fnames[];
  ulong  zip_offsets[];
  uint   pack_size[];
  uint   unpack_size[];
};
struct DATA_DESCRIPTOR
{
  uint crc_32;
  uint pack_size;
  uint unpack_size;
};
//
DATA_DESCRIPTOR data_descriptor;
ZIP_HEADER      zip_header;
ZIP_ENTRYES     zip_entryes;
uchar           key[] = {1,0,0,0};
bool            f_found;
uchar           f_name[];
bool            is_descr;
//+------------------------------------------------------------------+
//| Get entryes in ZIP file                                          |
//+------------------------------------------------------------------+
uint GetEntryesZip( int handle, ZIP_ENTRYES &f_entr )
{
//--- Check valid file handle
  if ( handle != INVALID_HANDLE )
  {
    f_entr.file_count = 0;
//---      
    ulong file_size = FileSize( handle );
    if ( file_size > 0 ) 
    {
//---Set file position to "0"
      FileSeek( handle, 0, SEEK_SET );
//---Build table           
      while ( FileTell( handle ) < ( file_size - uint_size ) )
      {
        zip_header.sign = FileReadInteger( handle, uint_size );
//---        
        if ( zip_header.sign == 0x04034b50 )
        {
          FileSeek( handle, -4, SEEK_CUR );
          f_entr.file_count++;
          FileReadStruct( handle, zip_header );
//---Check needed version 
          if ( ( zip_header.a_version != 0x0014 ) && ( f_entr.file_count == 1 ) )
          {
            Print( "Unsupported version!" );
            f_entr.file_count = 0;
            return( f_entr.file_count );
          }
          if ( ( zip_header.extr_field_len != 0 ) && ( f_entr.file_count == 1 ) )
          {
            Print( "File compressed using ZIP64 format!" );
            f_entr.file_count = 0;
            return( f_entr.file_count );
          }
//---Resize out data
          ArrayResize( f_entr.pack_size, f_entr.file_count );
          ArrayResize( f_entr.unpack_size, f_entr.file_count );   
          ArrayResize( f_entr.zip_fnames, f_entr.file_count );
          ArrayResize( f_entr.zip_offsets, f_entr.file_count );           
//---Check for sizes using extra bit
          if ( ( ( zip_header.bit_flag & 4 ) >> 2 ) == 1 )
          {
            is_descr = true; 
          }  
          else
          {
            is_descr = false;
            f_entr.pack_size[ f_entr.file_count - 1] = zip_header.pack_size;
            f_entr.unpack_size[ f_entr.file_count - 1] = zip_header.unpack_size;
          }
//---Get current file name
          ArrayResize( f_name, zip_header.fn_len );
          f_entr.zip_fnames[f_entr.file_count - 1] = ""; 
          uint fn_res = FileReadArray( handle, f_name, 0, int( zip_header.fn_len ) );
          for ( int i = 0; i < int( fn_res ); i++ )
           f_entr.zip_fnames[f_entr.file_count - 1] += CharToString( f_name[i] );
//---Store offset
          f_entr.zip_offsets[ f_entr.file_count - 1] = FileTell( handle );
//---Get descriptor, if present
          if ( is_descr )
          {
            uint sign;
            while ( FileTell( handle ) < ( file_size - uint_size ) )
            {
              sign = FileReadInteger( handle, uint_size );
              if ( ( sign == 0x04034b50 ) || ( sign == 0x02014b50 ) )
              {
//---Seek back for read descriptor              
                FileSeek( handle, -( uint_size + descr_size ), SEEK_CUR );
                FileReadStruct( handle, data_descriptor );
                f_entr.pack_size[ f_entr.file_count - 1] = data_descriptor.pack_size;
                f_entr.unpack_size[ f_entr.file_count - 1] = data_descriptor.unpack_size;
//---Align file positon to new file
                FileSeek( handle, f_entr.zip_offsets[f_entr.file_count - 1] +
                                  f_entr.pack_size[ f_entr.file_count - 1], SEEK_SET ); 
                break;                                  
              }
            }
          }
          else            
//---Seek to new file          
          FileSeek( handle, f_entr.pack_size[ f_entr.file_count - 1 ], SEEK_CUR ); 
        }
      }
    }
    else
    {
      Print( "Invalid zip file size!" );
    }
  }
  else
  {
    Print( "Invalid zip file handle!" );
  }  
  return( f_entr.file_count );
}
//+------------------------------------------------------------------+
//| Get file from ZIP file                                           |
//+------------------------------------------------------------------+
bool GetFile( const int handle, const ulong offset, const uint pack_size,
              const uint unp_size, uchar &unp_data[] )
{
  if ( ( handle != INVALID_HANDLE ) && ( pack_size != 0 ) && ( unp_size != 0 ) )
  {
    uchar pack_data[];
    ArrayResize( pack_data, pack_size + hdr_size );
    FileSeek( handle, offset, SEEK_SET );
    uint ar_res = FileReadArray( handle, pack_data, hdr_size, pack_size );
    if ( ar_res == pack_size )
    {
      pack_data[0] = 0x78;
      pack_data[1] = 0x5E;
      ResetLastError();
      uint dec_res = CryptDecode( CRYPT_ARCH_ZIP, pack_data, key, unp_data );
      if ( dec_res == unp_size )
      {
        return( true );
      }
      else
      {
        Print( "Last error = ", GetLastError() );
      }
    }
  }
  return( false );
}


吹き出しです。

//+------------------------------------------------------------------+
//|                                                     Zip_test.mq5 |
//|                                          Copyright 2015, Mikalas |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, Mikalas"
#property link      "https://www.mql5.com"
#property version   "1.00"
//
#include "Zip_decoder.mqh";
//
int         zip_handle;
ZIP_ENTRYES entries;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   string file_name = "Settings.zip";
   zip_handle = FileOpen( file_name, FILE_READ | FILE_BIN );
   
   if ( zip_handle != INVALID_HANDLE )
   {
     uint zip_files = GetEntryesZip( zip_handle, entries );
     if ( zip_files > 0 )
     {
//---Get 3 file from zip archive ([2])     
       uchar file_data[];
       if ( GetFile( zip_handle, entries.zip_offsets[2], entries.pack_size[2],
                     entries.unpack_size[2], file_data ) )
       {
         Print(" Unpack done.");
       }
       else
       {
         Print("Unpack failed!");
       }
     }
   }  
//---
   return(INIT_SUCCEEDED);
  }
void OnDeinit( const int reason )
{
  if ( zip_handle != INVALID_HANDLE ) FileClose( zip_handle );
}
 
Mikalas:

バシリー!

あなたからの返事を待たずに。(MQがビルド1100で変更を実装する時間があったかどうかは分かりませんが)

デコーダーです。

吹き出しです。

時間がなかった。Bild 1100は、私たちの議論が始まる前に紹介されました。
 
-Aleks-:

Mikalas さん、デコードとエンコードのコードをライブラリ化して、解凍完了をチェックすることは可能でしょうか?

はい、もちろんです。それが、近い将来、私が行うことになるのです。荷造り・荷ほどきがあります。アーカイブへのファイルの追加と削除。CryptDecodeが失敗しない限りは。
 
C-4:
もちろんです。近い将来、そうなりますね。荷造り・荷ほどきがあります。アーカイブへのファイルの追加と削除。CryptDecodeが失敗しないことが最大のポイントです。

バシリー!

ZIP包装は必要ですか?

その価値はないと思う。

1.ZIPをベースにしたデータベースを構築したい場合は、関係ないでしょう。

まもなくMQはデータベースと連携する標準機能を追加する予定です(Renatが調査しました)。

2.uintより大きなファイルサイズでは 解決できない。

ulongサイズにはZIP64圧縮があるはずです。

3.MT5のデータがどのように圧縮されているのか、正確に把握していない方

大きなファイル(uintサイズでも)は、その可能性があります。

大きなファイル(整数サイズでも)は何時間もかけて圧縮されます。

4.アーカイブにファイルを「詰め込む」ためには、かなり多くの情報を

多くの情報をメモリに保存しているHARDWAREがあります。

強く忠告しておきますが...。

 

私は古い考え方かもしれませんが、私にとってアーカイブは、インターネット上のデータ転送を高速化するために興味深いものです。ローカルで大容量のハードディスクを使用すると、ファイルサイズが 意味をなさなくなり、データベースは限られた範囲の人々のものになり、プログラマーとユーザーの追加の知識が必要となるため、実装にコストがかかります。

確かにzipは圧縮、特にテキストの圧縮ではrarにかなり劣りますが、これは少し悲しいことです。

 
Mikalas:

バシリー!

ZIP包装は必要ですか?

その価値はないと思う。

私はそうではないと思います。

ミカラス

1.ZIPをベースにしたデータベースを構築したい場合は、関係ないでしょう。

まもなくMQはデータベースと連携する標準機能を追加する(Renatが調査した)

いや、ZIPはDBの代替品として面白くない。だからZIPで悩む意味がないんだよ。

ミカラス

2.uintより大きなファイルサイズでは、問題を解決できません。

ulongサイズにはZIP64圧縮が必要です。

WinZipやWinRarのアナログを作るという目標はない。最も基本的なアーカイブのみ。4GB以上のファイルを圧縮しようとは誰も思わないでしょう。

ミカラス

3.MT5のデータが具体的にどのように圧縮されているのかがわからない。

大きなファイル(uintサイズでも)は、そのサイズに合わせて

偶数uintサイズ)は、1時間圧縮されます!

4.アーカイブにファイルを「詰め込む」ためには、かなり多くの情報を

多くの情報をメモリに保存しているHARDWAREがあります。

強くお勧めします...。

1.MQは遅い機能はやらないし、やるとしてもservicedeskからの要求に基づいて適時最適化する。CryptEncodeが 飛ぶのは、なんとなく自信があるんです。

2.速度が落ちることはありません。最新のMQL5の性能はご存じないでしょう。今のパソコンはメモリが多すぎる。数百メガバイトのファイルをダウンロードし、パックするのは朝飯前で、それ以上は必要ない。これらは別の仕事だからです。

 
Mikalas:

バシリー!

ZIP包装は必要ですか?

その価値はないと思う。

Expert Advisor から直接 Excel スプレッドシートにレポートを作成し、メールで送信することができます。これは、DLLを使用しない、標準的な機能だけになります。このようなライブラリは、マーケットプレイス製品の一部として配布することができます。これはほんの一例です。
 
C-4:

私はそうではないと思います。

いや、ZIPはDBの代替品として面白くない。だからZIPで悩む意味がないんだよ。

WinZipやWinRarのアナログを作るという目標はない。最も基本的なアーカイブのみ。4GBを超えるファイルを圧縮しようとは誰も思わないでしょう。

1.MQは遅い機能はやらないし、やるとしたらサービスデスクからのリクエストに基づき、タイムリーに彼らの仕事を最適化する。CryptEncodeが飛ぶのは、なんとなく自信があるんです。

2.速度が落ちることはありません。最新のMQL5の性能はご存じないでしょう。今のパソコンはメモリが多すぎる。数百メガバイトのファイルをダウンロードし、パックするのは朝飯前で、それ以上は必要ない。これらは別の仕事だからです。

Godspeed!
 
-Aleks-:

私は古い考え方かもしれませんが、私にとってアーカイブは、インターネット上のデータ転送を高速化するために興味深いものです。ローカルで大容量のハードディスクを使用すると、ファイルサイズが意味をなさなくなり、データベースは限られた範囲の人々のものになり、プログラマーとユーザーの追加の知識が必要となるため、実装にコストがかかります。

True Zipは、特にテキスト、rarの圧縮に著しく劣る - これは少し悲しいです。

全くその通りです。WebRequestによる 第三者サーバーとの通信は、送信情報のパッケージングを利用することでより高速になります。これも、パッケージのリロードが良い解決策となる考え方です。

-Aleks-:

しかし、zipは圧縮、特にテキストの圧縮ではrarに大きく劣り、ちょっと悲しいです。

与えられたものに感謝する。最も一般的な圧縮形式を扱う能力が、すべてのタスクの90%をカバーしていることを信じてください。ZIPで8割の冗長性を排除することに成功。次に来るのは、誰にも必要とされないオウムを追いかけることです。

 
Mikalas:
逝ってよし!
標準のZIPファイルの形式を調査しました。複雑ではありません。パックの仕方を「学ぶ」ために必要なのは、ヘッダー構造に似た2つの余分な構造をファイルの末尾に書くことです。だから、努力する価値があるのは明らかです。
理由: