CryptDecode avec modificateur CRYPT_ARCH_ZIP - Comment l'utiliser ? - page 10

 

Vasiliy !

Je n'ai pas attendu de réponse de votre part. (je ne sais pas si MQ a eu le temps d'implémenter les changements dans le build 1100)

Décodeur :

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


Appels :

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

Je n'ai pas attendu de réponse de votre part. (je ne sais pas si MQ a eu le temps d'implémenter les changements dans le build 1100)

Décodeur :

Appels :

Je n'ai pas eu le temps. Bild 1100 a été présenté avant le début de notre discussion.
 
-Aleks-:

Mikalas, est-il possible de faire le code de décodage et d'encodage comme une bibliothèque avec une vérification de l'achèvement du déballage ?

Oui, bien sûr. C'est ce que je vais faire dans un avenir proche. Il y aura de l'emballage et du déballage. Ajout et suppression de fichiers dans l'archive. Tant que CryptDecode n'échoue pas.
 
C-4:
Bien sûr. C'est ce que je vais faire dans un avenir proche. Il y aura de l'emballage et du déballage. Ajout et suppression de fichiers dans les archives. L'essentiel est que CryptDecode n'échoue pas.

Vasiliy !

L'emballage ZIP est-il nécessaire ?

Je ne pense pas que ça en vaille la peine.

1. Si vous voulez construire une base de données basée sur le ZIP, elle ne sera pas pertinente.

Bientôt, MQ ajoutera des fonctions standard pour travailler avec la base de données (Renat a fait une enquête).

2. Vous ne pouvez pas résoudre le problème avec des tailles de fichiers supérieures à uint.

Il devrait y avoir une compression ZIP64 pour les tailles ulong.

3. Vous ne savez pas exactement comment les données MT5 sont compressées.

Il est possible que des fichiers volumineux (même de taille uint)

Les gros fichiers (même de taille minuscule) seront compressés pendant des HEURES !

4. Pour "entasser" les fichiers dans une archive, vous devrez conserver un grand nombre d'informations dans les fichiers de l'archive.

beaucoup d'informations en mémoire - il y aura du HARDWARE !

Je le déconseille fortement....

 

Je pense sans doute à l'ancienne, mais pour moi, l'archivage est intéressant pour accélérer le transfert des données sur Internet. Avec des disques durs de grande taille , la taille du fichier perd de sa pertinence, la base de données ne sera destinée qu'à un nombre limité de personnes et sa mise en œuvre est coûteuse, car elle nécessite des connaissances supplémentaires de la part du programmeur et de l'utilisateur.

Il est vrai que zip est considérablement inférieur à rar en matière de compression, notamment de texte - ce qui est un peu triste.

 
Mikalas:

Vasiliy !

L'emballage ZIP est-il nécessaire ?

Je ne pense pas que ça en vaille la peine.

Je pense le contraire.

Mikalas:

1. Si vous voulez construire une base de données basée sur le ZIP, elle ne sera pas pertinente.

Bientôt, MQ ajoutera des fonctions standard pour travailler avec les bases de données (Renat a fait une enquête).

Non, zip n'est pas intéressant comme alternative à DB. Ce n'est pas pour ça que ça vaut la peine de s'occuper de Zip.

Mikalas:

2. Vous ne pouvez pas résoudre le problème avec des tailles de fichiers supérieures à uint.

Il doit y avoir une compression ZIP64 pour la taille ulong.

Je n'ai pas l'intention de créer un analogue de WinZip ou WinRar. Seulement les archives les plus basiques. Personne ne pensera même à compresser des fichiers de plus de 4 Go.

Mikalas:

3. Vous ne savez pas comment les données MT5 sont compressées.

Il est possible que les gros fichiers (même de taille uint) soient

même de taille uint) seront comprimés pendant une HEURE !

4. Pour "entasser" les fichiers dans une archive, vous devrez conserver un grand nombre d'informations dans les fichiers de l'archive.

beaucoup d'informations en mémoire - il y aura du HARDWARE !

Je vous déconseille fortement d'aller sur ....

1. MQ ne fait pas de fonctions lentes, et si c'est le cas, il les optimise en temps voulu, en fonction des demandes de servicedesk. Je suis en quelque sorte confiant que CryptEncode va voler.

2. Il n'y aura pas de ralentissement. Vous ne savez pas ce dont un MQL5 moderne est capable en termes de performances. Les ordinateurs d'aujourd'hui ont trop de mémoire. Télécharger et emballer un fichier de quelques centaines de mégaoctets est un jeu d'enfant, et vous n'avez pas besoin de plus. Car ce sont d'autres tâches.

 
Mikalas:

Vasiliy !

L'emballage ZIP est-il nécessaire ?

Je ne pense pas que ça en vaille la peine.

Saviez-vous que l'implémentation de fichiers zippés, par exemple, ouvre la voie à la création de fichiers docx et xmlx. Cela signifie que directement depuis votre Expert Advisor, vous pouvez créer une feuille de calcul Excel avec le rapport et l'envoyer par mail, par exemple. Il s'agira uniquement de la fonctionnalité standard, sans l'utilisation de DLL. Ces bibliothèques peuvent être distribuées dans le cadre des produits Marketplace. Ce n'est qu'un exemple.
 
C-4:

Je pense le contraire.

Non, zip n'est pas intéressant comme alternative à DB. Ce n'est pas pour ça que ça vaut la peine de s'occuper de Zip.

Je n'ai pas l'intention de créer un analogue de WinZip ou WinRar. Seulement les archives les plus basiques. Personne ne songerait même à compresser des fichiers de plus de 4 Go.

1. MQ ne fait pas de fonctions lentes, et si c'est le cas, il optimisera leur travail en temps voulu, en fonction des demandes du service desk. Je suis en quelque sorte confiant que CryptEncode va voler.

2. Il n'y aura pas de ralentissement. Vous ne savez pas ce dont un MQL5 moderne est capable en termes de performances. Les ordinateurs d'aujourd'hui ont trop de mémoire. Télécharger et emballer un fichier de quelques centaines de mégaoctets est un jeu d'enfant, et vous n'avez pas besoin de plus. Car ce sont d'autres tâches.

Bon vent !
 
-Aleks-:

Je pense sans doute à l'ancienne, mais pour moi, l'archivage est intéressant pour accélérer le transfert des données sur Internet. Avec des disques durs de grande taille, la taille du fichier perd de sa pertinence, la base de données ne sera destinée qu'à un nombre limité de personnes et sa mise en œuvre est coûteuse, car elle nécessite des connaissances supplémentaires de la part du programmeur et de l'utilisateur.

True zip est nettement inférieur en matière de compression, en particulier pour le texte, rar - ce qui est un peu triste.

Tout à fait vrai. Communiquer avec un serveur tiers via WebRequest sera beaucoup plus rapide en utilisant le conditionnement des informations envoyées. C'est une autre idée pour laquelle le rechargement de l'emballage est une bonne solution.

-Aleks-:

Cependant, zip est nettement inférieur à rar en matière de compression, notamment de texte - ce qui est un peu dommage.

Apprécier ce qui nous a été donné. Croyez-moi, la capacité de travailler avec le format de compression le plus populaire couvre 90% de toutes les tâches. 80% de la redondance est éliminée avec succès avec zip. La suite, c'est la chasse aux perroquets dont personne n'a besoin.

 
Mikalas:
Bon débarras !
J'ai étudié le format du fichier zip standard. Ce n'est pas compliqué. Tout ce que vous devez faire pour "apprendre" à empaqueter est d'écrire deux structures supplémentaires à la fin du fichier, semblables à une structure d'en-tête. Donc ça vaut clairement le coup de jouer.