1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 013
    Points : 4 954
    Points
    4 954
    Billets dans le blog
    1

    Par défaut Algorithme de compression avec en-tête "fixe"

    Bonjour,

    J'ai en ma possession une base de données, et un outil client.

    Dans la base de données, j'ai des données sous forme binaire (BLOB).

    Depuis l'interface client, je peux voir que ces données renferment des données strucurées, et notamment du texte.

    J'ai tenté de récupérer le contenu de ces BLOB sous forme de fichiers, mais à la vision dans un éditeur Hexa ou de texte, je ne vois pas le moindre caractère intelligible.

    J'en déduit que :
    - soit les données sont compressées
    - soit elles sont cryptées

    Étant donné le volume de données affichée dans l'application en rapport avec la taille des données en base, j'en déduis qu'elles sont effectivement compressées.
    En toute logique, elle ne sont pas cryptées (leur nature ne nécessite aucunement un encryptage).

    J'ai tenté de sauvegarder le contenu d'un BLOB dans un fichier, puis de le décompresser avec 7zip : rien n'y fait, il ne comprends pas du tout ce que c'est que ces données.

    J'en déduis que :
    - soit j'ai affaire à un "développeur" qui a inventé son propre algo de compression plutôt que de reprendre un standard (gzip, bzip2, etc.)
    - soit le "développeur" s'est dit "tiens, je vais gagner 5 octet par blob en ne stockant pas le header du flux compressé"

    J'ai donc entrepris de rajouter une entête et un pied de document pour le rendre conforme mon fichier aux spécifications de GZip et BZip2.
    Mais après moultes tentatives, je me rends compte que pour ces deux algo :
    - J'ai besoin de la taille du flux d'origine
    - Du CRC32 du flux d'origine

    Hors je n'ai ni l'un ni l'autre : dans la base c'est qu'une autre colonne qui contient la taille du BLOB "en l'état"... Genre le "développeur" sait pas récupérer la taille d'un BLOB en base alors il la stock, mais à côté de ça il m'emmerde à compresser son truc comme un porc.

    Bref, je continue toujours à essayer de trouver comment ça a pu être compressé.
    Je recherche un algo "standard" dont l'entête serait "fixe" (c'est à dire non dépendante du flux d'origine, mais pouvant intégralement être déduire du flux généré).

    Une idée ?
    On ne jouit bien que de ce qu’on partage.

  2. #2
    Membre expert
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2002
    Messages
    2 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : mai 2002
    Messages : 2 447
    Points : 3 844
    Points
    3 844

    Par défaut

    salut

    il n'est pas simple de t'aider sans avoir un exemple concret .
    par exemple une copie d'ecran du rendu de ton appli et l'extraction de ton blob correspondant a ce que tu affiche

    est tu sur que ce n'est pas du pdf ou une image ... genre un format connu
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 013
    Points : 4 954
    Points
    4 954
    Billets dans le blog
    1

    Par défaut

    Bonjour, et merci pour votre réponse.

    Voici en pièce jointe le résultat d'une extraction des données d'une ligne (compressé en 7z), et une capture d'écran de l'application avec les données censées être contenues dans ce fichier.

    Pour faire simple, dans ma base j'ai des tables (jusque là tout va bien) et une table d'historique.
    Chaque ligne de chaque table a une ligne dans la table d'historique, qui ne contient rien d'autre que ce champ blob.
    Certaines lignes de cette table faisant plus de 100 Mo, j'en déduis que le détail de l'historique est bien stocké dans ce champ.

    Code d'extraction des données :
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
    
    namespace LVarDataReader
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Connecting to SQL Server");
                using (SqlConnection cnx = new SqlConnection(@"Server=.\SQL2016;Integrated Security=true;Initial Catalog=crm_offline"))
                {
                    cnx.Open();
    
                    Console.WriteLine("Loading line H0 id 13310103650306");
                    SqlCommand cmd = cnx.CreateCommand();
                    cmd.CommandText = "select lvardata from offline_web_h0 where id = 13310103650306";
                    byte[] lvardata = (byte[])cmd.ExecuteScalar();
    
                    Console.WriteLine("Writing data to a file");
                    using (FileStream fs = File.Create(@"c:\in\lvardata.dat", lvardata.Length, FileOptions.WriteThrough))
                    {
                        fs.Write(lvardata, 0, lvardata.Length);
                        fs.Flush();
                        fs.Close();
                    }
                    Console.WriteLine("File created");
    
                    Console.WriteLine("Disconnecting from SQL Serer");
                    cnx.Close();
    
                    Console.WriteLine("The End");
                    Console.ReadKey(true);
                }
            }
        }
    }
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    On ne jouit bien que de ce qu’on partage.

  4. #4
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 343
    Points : 4 571
    Points
    4 571
    Billets dans le blog
    5

    Par défaut

    Bonjour,

    Si tu es sur que tes données sont compressées, tu peux essayer d'utiliser l'algorithme deflate qui est fourni en standard avec le Framework .Net. Il y a peut de chance que le développeur ait développé son propre algo (c'est pas impossible, mais peu probable).

    Sinon, peut-être ton flux est-il sérialisé ? Un standard, il y a les BinaryFormatter. Mais il existe d'autres moyen de sérialisation binaire (par exemple, protobuf de Google).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 013
    Points : 4 954
    Points
    4 954
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par François DORIN Voir le message
    Si tu es sur que tes données sont compressées, tu peux essayer d'utiliser l'algorithme deflate qui est fourni en standard avec le Framework .Net.
    C'est vrai que je me suis attelé à transformer le flux en fichier GZ, mais j'ai pas pensé à faire directement un DEFLATE dessus (faut dire que la compression c'est pas trop mon truc, j'ai pas du tout de réflexes...)

    Ceci dit, le programme dispose d'une classe proprio "GZIP" et soit j'ai pas réussi à m'en servir, soit le flux n'était pas compatible : en tout cas, ça marchait pas

    Petite info complémentaire : le programme est ancien. Il a été partiellement réécrit en C#, mais une bonne partie est toujours en C++ (des années 90) : la méthode de compression/sérialisation est donc de cette époque.
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    3 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : février 2010
    Messages : 3 013
    Points : 4 954
    Points
    4 954
    Billets dans le blog
    1

    Par défaut

    C'est ni Deflate ni GZip standard : le code suivant provoque une erreur comme quoi le GZIP Magic Number n'est pas bon, et si je prends la classe DeflateStream j'ai doit à une donnée qui ne correspond pas à son complément...

    A moins que je ne me serve mal de ces classes... Je te laisse vérifier mon code :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
                    Console.WriteLine("Inflate data");
                    GZipStream ds = new GZipStream(ms, CompressionMode.Decompress);
     
                    Console.WriteLine("Writing data to a file");
                    using (FileStream fs = File.Create(@"c:\in\lvardata.dat", lvardata.Length, FileOptions.WriteThrough))
                    {
                        byte[] inflate = new byte[4096];
                        int read = 0;
                        while ((read = ds.Read(inflate, 0, inflate.Length)) > 0)
                        {
                            Console.WriteLine("Write a chunk");
                            fs.Write(lvardata, 0, read);
     
                            if (ds.Position == ds.Length)
                            {
                                break;
                            }
                        }
                        fs.Flush();
                        fs.Close();
                    }
                    Console.WriteLine("File created");
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 343
    Points : 4 571
    Points
    4 571
    Billets dans le blog
    5

    Par défaut

    Informations intéressantes !

    Juste pour savoir, as-tu tester de créer deux enregistrements similaire (si possible vide) et de comparer le résultat en BD ?
    Si les BLOB sont radicalement différent, ils sont sans doute chiffrés (en pratique, on compresse souvent un flux avant de le chiffrer).

    Citation Envoyé par StringBuilder
    Petite info complémentaire : le programme est ancien. Il a été partiellement réécrit en C#, mais une bonne partie est toujours en C++ (des années 90) : la méthode de compression/sérialisation est donc de cette époque.
    Il faudrait donc pouvoir appeler directement les algo existant. Ce que tu as essayé de faire d'après ce que j'ai compris.

    Difficile sans plus d'information de pouvoir t'aider...
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  8. #8
    Rédacteur/Modérateur

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    juillet 2016
    Messages
    1 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juillet 2016
    Messages : 1 343
    Points : 4 571
    Points
    4 571
    Billets dans le blog
    5

    Par défaut

    Citation Envoyé par StringBuilder Voir le message
    C'est ni Deflate ni GZip standard : le code suivant provoque une erreur comme quoi le GZIP Magic Number n'est pas bon, et si je prends la classe DeflateStream j'ai doit à une donnée qui ne correspond pas à son complément...

    A moins que je ne me serve mal de ces classes... Je te laisse vérifier mon code :
    J'aurais fait plus simple :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                    using(GZipStream ds = new GZipStream(ms, CompressionMode.Decompress))
                    using (FileStream fs = File.Create(@"c:\in\lvardata.dat", lvardata.Length, FileOptions.WriteThrough))
                    {
                        ds.CopyTo(fs);
                    }

    Mais rien ne me choque dans ton code.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

Discussions similaires

  1. Réponses: 14
    Dernier message: 29/07/2010, 15h50
  2. algorithme de compression d'image Fixe avec EBCOT
    Par rufa11 dans le forum Traitement d'images
    Réponses: 0
    Dernier message: 30/05/2010, 08h21
  3. algorithme de compression d'image Fixe avec EBCOT
    Par rufa11 dans le forum Imagerie
    Réponses: 0
    Dernier message: 30/05/2010, 08h17
  4. Tableau avec en-tête fixe et largeurs de colonnes identiques
    Par arthuro45 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 24/08/2009, 10h34
  5. ScrollPane avec en-tête fixe
    Par S(ô.Ô)B dans le forum Fenêtres/Dialogues
    Réponses: 6
    Dernier message: 05/06/2009, 14h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo