<adresse_électronique CHEZ fournisseur POINT code_pays>
Copyright © 2002 Adrian J. Changchun
Copyright © 2017 Sébastien Marbrier
Copyright © Année de relecture Prénom Nom du relecteur
Article paru dans le n°079 de la Gazette Linux de juin 2002.
Cet article est publié selon les termes de la Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.
Table des matières
Tout possesseur d'une adresse électronique est susceptible de recevoir des pièces jointes dans une grande variété formats. Malheureusement, certains de ces formats ne peuvent être lus par les logiciels libres. Ceci est particulièrement vrai si nos potes virtuels font toujours un usage discutable et risqué des logiciels privateurs en combinaison avec leurs logiciels de courriels.
De nombreux partisans du logiciel libre adoptent comme ligne de conduite d'ignorer les courriels contenant des pièces-jointes liées aux logiciels privateurs, choisissant d'expliquer à l'expéditeur l'importance des standards ouverts. D'autres peuvent ne pas apprécier de s'exclure du plaisir procuré par les pièces-jointes envoyées entre correspondants. Si vous avez déjà rencontré cette situation, les techniques mises en lumière dans cet article peuvent apporter une solution partielle.
Un utilisateur de Linux
ne peut pas faire grand-chose si tout le contenu attaché est encodé par un algorithme jalousement tenu secret. Toutefois, il est très fréquent que le fichier problématique ne soit qu'une mince enveloppe propriétaire entourant un fatras de structures de données reposant sur des standards d’encodages connus.
Par exemple, certains documents MS Word™ envoyés sur internet incorporent en leur sein des images ordinaires au format JPG
ou PNG
.
Si nous trouvions le moyen de retirer l'enveloppe, la lecture de ces documents insérés serait très simple.
Les sections suivantes décrivent comment y parvenir au moyen de quelques programmes en Python associés à quelques outils de visualisation et de manipulation d'image disponibles dans la plupart des distributions Linux
.
Avant de s'attaquer au problème des images incorporées, nous pouvons facilement visualiser n'importe quel texte en clair grâce à l'utilitaire strings :
strings fichier.proprio
|
less
Ceci produira en sortie toute chaîne de caractères ayant une longueur minimale de quatre octets, composée de caractères ASCII lisibles.
Naturellement, il y aura en sortie bien d'autres choses que des phrases intelligibles.
La plupart n'auront aucune utilité, mais le texte lisible est facilement repéré. Les outils strings récupéreront également les informations d'entête lisibles à l'intérieur même des images éventuellement présentes dans un fichier.
Les fichiers JPEG
contiennent la chaîne « JFIF » dans l'entête.
Ceci nous donne la possibilité de vérifier rapidement quels sont les types d'images contenues dans un fichier ainsi que leur nombre.
strings fichier.proprio
|
grep JFIF
strings -n
3
fichier.proprio
|
grep PNG
strings fichier.proprio
|
grep GIF8
L'option -n
3
nous permet de détecter les chaînes en clair de 3 caractères.
Toutes les occurrences de JFIF ne correspondent pas nécessairement à une image JPEG
car le document peut avoir JFIF dans une zone de texte.
— bien que ce soit rarement le cas dans les pièces jointes les plus souvent envoyées.
Il nous faut trouver où se trouve exactement chaque image dans le fichier. Un peu de Python nous aidera à trouver les images insérées et retourner leurs positions sous forme de décalage binaire :
from string import find #lit dans les données propriétaires fh = open( "fichier.proprio" ) dat = fh.read() fh.close() #cherche la chaîne JFIF x = -1 while 1: x = find(dat,"JFIF",x+1) if x<0: break #Le début réel du fichier commence 6 octets plus haut print x - 6
Ceci nous donnera la position en octets de chaque fichier JPEG
bien que toutes les positions ne soient pas garanties pour un fichier valide.
On peut facilement l'étendre pour manipuler les images GIF
et PNG
:
Programme 1
#!/usr/bin/python from string import find from sys import argv entetes = [("GIF8",0), ("PNG",1), ("JFIF",6)] fichier = "fichier.proprio" if len(argv)>1: fichier = argv[1] fh = open(fichier ) dat = fh.read() fh.close() for kw,off in entetes: x = 0 while 1: x = find(dat,kw,x+1) if x<0: break print kw,"le fichier commence à la position",x - off
Notez que le fichier image commence quelques octets avant les chaînes « PNG » ou « JFIF ».
Maintenant que nous sommes capables de localiser approximativement la position de chaque image, comment les afficher ?
L'utilitaire d'affichage ImageMagick display peut nous y aider. Supposons que notre fichier propriétaire contienne une image JPEG
commençant à l'octet 1000.
Grâce à tail, on retire tous les octets qui précèdent et on envoie le reste à display.
tail -c
+1001
fichier.proprio
|
display -
Notez que tail -c
commence le comptage des octets à 1.
Dans le cas où il y aurait plusieurs dizaines d'images, nous pouvons adapter notre précédent programme Python
pour automatiser le traitement.
Programme 2
#!/usr/bin/python from string import find from sys import argv from os import system entetes = [("GIF8",0), ("PNG",1), ("JFIF",6)] fichier = "fichier.proprio" if len(argv)>1: fichier = argv[1] fh = open(fichier ) dat = fh.read() fh.close() for kw,off in entetes: x = 0 while 1: x = find(dat,kw,x+1) if x<0: break system("tail -c +%d %s | display -" % (x - off + 1, filepath))
ImageMagick rejette toutes les données reçues qui se trouvent au-delà de la fin du segment d'image. Si nous voulons complètement séparer les données de l'image pour les stocker sous forme de fichiers individuels, nous devons également trouver la fin de chaque image. L'utilisation d'une version modifiée de notre algorithme de découpe de trame binaire est un moyen d'y parvenir. Programme 3
#!/usr/bin/python from string import find from sys import argv from commands import getstatusoutput entetes = [("GIF8",0,"giftopnm","gif"), ("PNG",1,"pngtopnm","png"), ("JFIF",6,"djpeg","jpg")] fichier = "fichier.proprio" if len(argv)>1: fichier = argv[1] fh = open(fichier ) dat = fh.read() fh.close() inum = 0 for kw,off,conv,ext in entetes: x = -1 while 1: x = find(dat,kw,x+1) if x<0: break deb = x - dec #candidat image localisé -- cherche la fin par découpe binaire s1 = len(dat) - x s0 = 1 sz = s1 while s0<s1: (stat,output) = getstatusoutput("tail -c +%d %s | head -c %d | %s >/dev/null" % (deb + 1, fichier, sz, conv)) if stat: #echec -- candidat probablement trop petit if sz == s1: #echec -- candidat trop petit print "Echec... pas d'image" break elif sz == s0: #longueur trouvée -- écriture de l'image nomimage = "image%03d.%s" % (inum, ext) print "écriture",nomimage fh = open( nomimage, "w") fh.write(dat[deb :deb+s1]) fh.close() inum = inum + 1 break s0 = sz else: #semble trop gros -- essaie de réduire s1 = sz sz = int((s0+s1)/2)
On peut utiliser les utilitaires de décodage d'image giftopnm, djpeg et pngtopnm pour localiser la fin du fichier. Tout comme display ces outils rejettent les données d'entrées excédentaires après la fin du fichier image et se terminent sans erreur. Si toutefois, ils reçoivent une image tronquée ils retourneront une erreur et se termineront en échec. Le script Python envoie des données images de tailles variables à l'outil de décodage et son état d'exécution est utilisé pour viser la bonne taille du fichier demandé.
Cet article a montré comment écrire des scripts pour extraire de fichiers propriétaires les objets de données encodés par des standards ouverts et indépendants du matériel. Ce devrait être assez facile d'étendre ces scripts pour manipuler d'autres formats d'image et même d'autres types de données tels que les fichiers audio. Notez qu'il existe de nombreux formats de fichier qui contrarient les techniques décrites ici à cause d'une couche de chiffrement simple et/ou d'obscurcissement.
Même en ayant accès à l'application propriétaire adéquate pour lire unes pièce jointe spécifique, les scripts présentés plus haut peuvent être utiles pour éviter toute sorte de virus macro ou d'exploitation de faille de sécurité propres à cette application.
Et terminons sur une note d'avertissement. La législation dans certains pays est suffisamment vague pour être interprétée de telle sorte que ces scripts peuvent être considérés comme des techniques illégales de contournement du droit d'auteur. Ceci peut être pertinent ou non selon votre pays de résidence. C'est toujours le cas avec les systèmes mêlant les logiciels libres et propriétaires, votre position peut varier.
La Python Imaging Library (PIL) apporte la possibilité de travailler les images depuis un programme plus grand. Vous pouvez ouvrir une image et obtenir son type et ses dimensions, la transformer, créer des vignettes, etc. –Iron.
Adrian J Chung Lorsqu'il n'enseigne pas l'informatique à l'Université des Indes Orientales, à Trinidad, Adrian écrit des scripts système pour piloter un réseau d'ordinateurs sous Linux et mène des expériences en interfaçant divers environnements de script avec différents systèmes de rendu maison et des librairies de visualisations de données.
L'adaptation française de ce document a été réalisée dans le cadre du Projet de traduction de la Gazette Linux.
Vous pourrez lire d'autres articles traduits et en apprendre plus sur ce projet en visitant notre site : http://www.traduc.org/Gazette_Linux.
Si vous souhaitez apporter votre contribution, n'hésitez pas à nous rejoindre, nous serons heureux de vous accueillir.