CryptDecode con modificatore CRYPT_ARCH_ZIP - Come usare? - pagina 10

 

Vasiliy!

Non ho aspettato una tua risposta. (non so se MQ ha avuto il tempo di implementare i cambiamenti nella build 1100)

Decoder:

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


Richiami:

//+------------------------------------------------------------------+
//|                                                     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:

Vasiliy!

Non ho aspettato una tua risposta. (non so se MQ ha avuto il tempo di implementare i cambiamenti nella build 1100)

Decoder:

Richiami:

Non ha avuto tempo. Bild 1100 è stato introdotto prima che iniziasse la nostra discussione.
 
-Aleks-:

Mikalas, è possibile rendere il codice di decodifica e codifica come una libreria con un controllo per il completamento dello spacchettamento?

Sì, certo. Questo è quello che farò nel prossimo futuro. Ci sarà da imballare/disimballare. Aggiunta e rimozione di file dall'archivio. Finché CryptDecode non fallisce.
 
C-4:
Certo. Questo è quello che farò nel prossimo futuro. Ci sarà da imballare/disimballare. Aggiunta e rimozione di file dall'archivio. La cosa principale è che CryptDecode non fallisce.

Vasiliy!

L'imballaggio ZIP è necessario?

Non credo che ne valga la pena.

1. Se vuoi costruire un database basato su ZIP, non sarà rilevante.

Presto MQ aggiungerà funzioni standard per lavorare con il database (Renat ha fatto un sondaggio).

2. Non puoi risolvere il problema con file di dimensioni maggiori di uint.

Ci dovrebbe essere la compressione ZIP64 per le dimensioni ulong.

3. Non sai esattamente come vengono compressi i dati di MT5

È possibile che file di grandi dimensioni (anche di dimensione uint)

I file di grandi dimensioni (anche di dimensioni uint) saranno compressi per ORE!

4. Per "stipare" i file in un archivio, dovrete tenere un bel po' di informazioni in

un sacco di informazioni in memoria - ci sarà HARDWARE!

Lo sconsiglio vivamente....

 

Probabilmente sto pensando alla vecchia maniera, ma per me l'archiviazione è interessante per accelerare il trasferimento dei dati su Internet. Localmente, con dischi rigidi di grandi dimensioni, la dimensione del file perde la sua rilevanza, e il database sarà per una gamma limitata di persone, ed è costoso da implementare, in quanto richiederà ulteriori conoscenze da parte del programmatore e dell'utente.

È vero che zip è notevolmente inferiore a rar nella compressione, soprattutto del testo - il che è un po' triste.

 
Mikalas:

Vasiliy!

L'imballaggio ZIP è necessario?

Non credo che ne valga la pena.

Io penso il contrario.

Mikalas:

1. Se vuoi costruire un database basato su ZIP, non sarà rilevante.

Presto MQ aggiungerà funzioni standard per lavorare con i database (Renat ha fatto un sondaggio)

No, zip non è interessante come alternativa a DB. Non è per questo che vale la pena preoccuparsi della zip.

Mikalas:

2. Non potete risolvere il problema con file di dimensioni maggiori di uint.

Ci deve essere la compressione ZIP64 per le dimensioni ulong.

Non ho l'obiettivo di creare un analogo di WinZip o WinRar. Solo gli archivi più elementari. Nessuno penserà mai a comprimere file più grandi di 4 GB.

Mikalas:

3. Non sai come esattamente vengono compressi i dati di MT5.

È possibile che file di grandi dimensioni (anche di dimensioni uint) siano

anche uint size) sarà compresso per ORE!

4. Per "stipare" i file in un archivio, dovrete tenere un bel po' di informazioni in

un sacco di informazioni in memoria - ci sarà HARDWARE!

Consiglio vivamente contro....

1. MQ non fa funzioni lente, e se lo fa, le ottimizza in modo tempestivo, in base alle richieste di servicedesk. Sono in qualche modo fiducioso che CryptEncode volerà.

2. Non ci saranno rallentamenti. Non sapete di cosa sia capace un moderno MQL5 in termini di prestazioni. I computer di oggi hanno troppa memoria. Scaricare e impacchettare un file di un paio di centinaia di megabyte è un gioco da ragazzi, e non avete bisogno di altro. Perché questi sono altri compiti.

 
Mikalas:

Vasiliy!

L'imballaggio ZIP è necessario?

Non credo che ne valga la pena.

Sapevi che l'implementazione dei file zippati, per esempio, apre la strada alla creazione di file docx e xmlx. Ciò significa che direttamente dal tuo Expert Advisor puoi creare un foglio Excel con il rapporto e inviarlo per posta, per esempio. Questa sarà solo la funzionalità standard, senza l'uso di DLL. Tali librerie possono essere distribuite come parte dei prodotti Marketplace. Questo è solo un esempio.
 
C-4:

Io penso il contrario.

No, zip non è interessante come alternativa a DB. Non è per questo che vale la pena preoccuparsi della zip.

Non ho l'obiettivo di creare un analogo di WinZip o WinRar. Solo gli archivi più elementari. Nessuno penserebbe mai di comprimere file più grandi di 4 GB.

1. MQ non fa funzioni lente, e se lo fa, ottimizza il loro lavoro in modo tempestivo, in base alle richieste del service desk. Sono in qualche modo fiducioso che CryptEncode volerà.

2. Non ci saranno rallentamenti. Non sapete di cosa sia capace un moderno MQL5 in termini di prestazioni. I computer di oggi hanno troppa memoria. Scaricare e impacchettare un file di un paio di centinaia di megabyte è un gioco da ragazzi, e non avete bisogno di altro. Perché questi sono altri compiti.

Buona fortuna!
 
-Aleks-:

Probabilmente sto pensando alla vecchia maniera, ma per me l'archiviazione è interessante per accelerare il trasferimento dei dati su Internet. Localmente, con dischi rigidi di grandi dimensioni, la dimensione del file perde la sua rilevanza, e il database sarà per una gamma limitata di persone, ed è costoso da implementare, in quanto richiederà ulteriori conoscenze da parte del programmatore e dell'utente.

Il vero zip è significativamente inferiore nella compressione, specialmente del testo, rar - il che è un po' triste.

Abbastanza vero. Comunicare con un server di terze parti tramite WebRequest sarà molto più veloce utilizzando il confezionamento delle informazioni inviate. Questa è un'altra idea per cui ricaricare l'imballaggio è una buona soluzione.

-Aleks-:

Tuttavia, zip è significativamente inferiore a rar nella compressione, specialmente del testo - il che è un po' spiacevole.

Apprezzare ciò che ci è stato dato. Credetemi, la capacità di lavorare con il formato di compressione più popolare copre il 90% di tutti i compiti. L'80% della ridondanza viene eliminata con successo con zip. Quello che viene dopo è la caccia ai pappagalli di cui nessuno ha bisogno.

 
Mikalas:
Che liberazione!
Ho studiato il formato del file zip standard. Non è complicato. Tutto quello che dovete fare per "imparare" a impacchettare è scrivere due strutture extra alla fine del file, simili a una struttura di intestazione. Quindi è chiaro che vale la pena di giocare.
Motivazione: