J’avais précédemment engagé mon honneur et promis de faire un premier billet sur le transfert sécurisé de données. Et je vais sans aucune vergogne me dédire, parce que j’ai un autre sujet sur le feu qui m’amuse plus. On verra le transfert une autre fois.

Je vous propose donc un premier billet sur la recherche de fichiers exemples. Quand on fait de la préservation numérique sérieuse, on a besoin d’un corpus de test assez conséquent pour vérifier que nos procédures d’identification, de validation ou d’analyse fonctionnent bien sur une diversité de fichiers. Où allons-nous donc trouver cette diversité si nous ne l’avons pas déjà sous la main ? Il y a plusieurs solutions complémentaires que je vais vous détailler ici. N’hésitez pas si vous en voyez d’autres à me les signaler en commentaire !

Une partie de ce billet est inspiré par le Starter Pack de PRONOM. PRONOM, vous le savez peut-être, est le registre de formats maintenu par les archives nationales du Royaume-Uni et enrichi par l’ensemble de la communauté de la préservation numérique. Le principe de PRONOM est qu’il associe à un format une « signature » (également appelée « nombre magique », magic number), c’est-à-dire un motif trouvé dans les fichiers et qui identifie sans équivoque (du moins on l’espère) un format de données précis. On pourra revenir sur l’identification de formats de fichiers, il y a beaucoup BEAUCOUP à dire là-dessus. Toujours est-il que lorsque vous disposez d’une signature candidate à l’identification de votre nouveau format préféré, il est nécessaire de l’essayer sur un corpus important pour s’assurer que :

  • Elle est assez spécifique (elle n’identifie pas de faux positifs, qui ne seraient pas du format attendu) ;
  • Elle est assez sélective (elle n’omet pas de faux négatifs, qui seraient du format attendu mais ne seraient pas identifiés).

Que ce soit pour l’identification ou pour tout autre opération de préservation, un corpus de test est toujours nécessaire. Je vais vous décrire cinq méthodes qui peuvent vous aider à réunir un corpus de fichiers. Les deux premières sont unitaires et peuvent être longuettes à mettre en œuvre, les trois suivantes permettent de récupérer plus de données d’un coup.

Google hacking / dorking

Le web contient des données de nature extrêmement différente – à l’occasion, je vous ferai peut-être une petite analyse des formats qu’on trouve en naviguant sur le web. Bref, si vous pensez qu’on ne trouve sur le web que des pages HTML, vous vous trompez. On peut y donner accès à toutes sortes de fichiers et si votre navigateur ne peut exploiter le format en question, vous pouvez toujours le télécharger pour l’ouvrir avec un logiciel spécialisé.

Cette première solution consiste donc à utiliser les critères de recherche spéciaux de Google afin de renvoyer uniquement des résultats correspondant à des fichiers d’un format donné. On utilisera pour cela une combinaison des trois critères suivants :

  • filetype:<extension> permet de rechercher uniquement des fichiers d’un format donné ;
  • inurl:<extension> permet de s’assurer que l’extension est présente dans l’URL du fichier.
  • "parent directory" permet de repérer les pages qui listent le contenu d’un système de fichiers accessible via le navigateur.

Par exemple, cette requête pour rechercher des fichiers Excel antérieurs à 2003.

L’ennui, c’est que le critère filetype reconnaît peu de formats différents, et que les requêtes ramèneront probablement pas mal de bruit. Enfin, il faudra naviguer entre les résultats et récupérer manuellement ce qui vous intéresse. Une autre méthode, toujours manuelle mais plus précise, est à tenter.

Recherche Github

Github, pour celles et ceux qui ne le sauraient pas, est un entrepôt de code, souvent libre, qui permet aux développeurs de publier leur code et de contribuer à des projets collaboratifs. De ce fait, il contient bien sûr du code dans de très nombreux langages de programmation, mais aussi des fichiers de données textuelles ou binaires en assez grand nombre.

On peut donc se rendre sur la plateforme et taper dans la barre de recherche la formule suivante :

path:/\.apk$/

(Remplacez « apk », qui correspond à l’extension des applications Android par toute autre extension qui vous intéresserait.)

La requête trouve uniquement les fichiers dont le chemin se termine par « .apk ». On utilise ici une expression régulière (d’où le fait que l’expression est entourée de barres obliques) qui utilise le symbole $ à la fin de l’expression pour s’assurer qu’il n’y a rien après la chaîne de caractères recherchée. La barre oblique inversée avant le point s’assure que l’on recherche bien le point qui précède une extension, sans quoi le point aurait sa valeur de caractère générique.

Cette solution est plus précise que la précédente, mais elle renvoie encore du bruit et elle est tout aussi manuelle. Tentons autre chose.

Corpus de fichiers en ligne

Il existe des corpus de fichiers déjà tout prêts, à disposition pour les besoins de développeurs. On citera notamment la Google Image Test Suite. Le sous-groupe « Outils et corpus » de la Cellule de veille nationale sur les formats avait réuni une liste de corpus en 2020. Il en existe de nombreux autres néanmoins, parmi lesquels je citerais :

En outre, le wiki Just Solve the File Format Problem indique régulièrement, dans une section Sample Files, des liens vers des ensembles de fichiers exemples. Par exemple, pour le format WARC : http://fileformats.archiveteam.org/wiki/WARC#Sample_files.

Mise à jour du 15/12/2024 : Tim Allison, Andy Jackson et Tyler Thorsted m’ont signalé les ressources supplémentaires suivantes :

Ces corpus sont fort précieux, mais on n’y trouve pas toujours des quantités suffisantes de fichiers d’un format particulier. Que faire alors ?

L’outil gh search code

Il s’agit ici d’une méthode plus avancée, notamment parce qu’elle met en œuvre une recherche dans Github via un outil en ligne de commande et demande une seconde étape afin de récupérer le contenu trouvé.

En bref, on va utiliser l’outil gh search code, qui dispose de critères de recherche précis :

  • --filename permet de rechercher un nom de fichier précis ;
  • --extension permet de rechercher par une extension.

Ici, on a la chance que le fichier qu’on recherche a toujours le même nom (les fichiers manifestes embarqués dans un paquet APK d’application Android se nomment obligatoirement AndroidManifest.xml). Ainsi, la ligne de commande suivante permet d’interroger Github et de ne ramener que ces fichiers :

gh search code --filename AndroidManifest.xml --extension xml -L 100 --json repository,path

Le nombre de résultats est limité à un nombre inférieur à 1000, que vous pouvez préciser par l’option -L <nombre>. En outre, l’option --json permet de produire directement un résultat au format JSON et de ne sortir que les champs « repository » (nom de l’entrepôt) et « path » (chemin vers le fichier).

Une fois qu’on dispose de ce résultat, on peut construire l’URL du fichier brut de la manière suivante :

https://raw.githubusercontent.com/ <nom_de_l_entrepot> /master/ <chemin>

En supposant qu’on ait pour nom d’entrepôt « Mardonbekmelsov/dars_5_3_getx » et pour chemin « android/app/src/main/AndroidManifest.xml », on aura donc l’URL d’accès au contenu brut suivant :

https://raw.githubusercontent.com/Mardonbekmelsov/dars_5_3_getx/master/android/app/src/main/AndroidManifest.xml

Il ne reste plus qu’à mettre en œuvre un outil de récupération automatique à qui on fournit une URL et qui télécharge le contenu. Je n’ai pas eu besoin de cette méthode pour les formats binaires, où on pourrait vouloir utiliser wget ou curl, en limitant le nombre de requêtes par seconde voire en variant le user-agent déclaré dans la requête pour espérer tromper la vigilance de Github… En revanche, je l’ai utilisée pour des formats textuels avec OpenRefine, et ça a très bien marché : j’ai récupéré tout le contenu du fichier XML.

La méthode est donc plutôt adaptée à des données textuelles structurées (XML, JSON, etc.). Pour des données binaires, je me suis intéressé à une cinquième solution.

Composition d’un corpus à partir des archives du web

Après des années à collecter cent à cent cinquante téraoctets de données en ligne par an, la BnF dispose d’une collection de contenus web nativement numériques de plus de deux pétaoctets. Dans cette collection, il est probable que l’on trouvera des exemples de fichiers dans les formats les plus divers.

Le format de fichier d’un contenu échangé sur le web est déclaré dans l’en-tête HTTP renvoyé par le serveur au client avec les données elles-mêmes1. Et les outils de moissonnage du web récupèrent aussi l’en-tête et l’inscrivent bien consciencieusement dans le fichier ARC ou WARC, sorte de conteneur où l’on range à la queue-leu-leu les données collectées sur le web avant de fermer la boîte quand elle est pleine (lorsqu’elle atteint 1 Go).

Dans l’en-tête, le format est déclaré sous la forme d’un type MIME (par ex. : application/pdf pour un PDF) dans le champ Content-Type. Bon, le problème c’est que ce n’est que déclaratif, donc si le développeur a déclaré n’importe quoi, on peut se retrouver avec un type MIME qui n’a pas de rapport avec le format réel des données (Sophie Derrot, qui a travaillé sur les archives du web pendant plusieurs années, me racontait qu’elles étaient tombées sur le type MIME application/jesuschrist). On reviendra peut-être sur la question du type MIME lors d’un prochain billet.

Notre chance, c’est que le logiciel qui pilote le magasin numérique de la BnF, SPAR, indexe au niveau de chaque conteneur ARC ou WARC le nombre de fichiers d’un type MIME donné. Il est donc possible, à l’aide d’une requête SPARQL un peu velue (la base de données de SPAR est un entrepôt de triplets), de récupérer une liste de X paquets contenant le plus grand nombre de fichiers d’un type MIME donné.

Une fois qu’on a récupéré les paquets en question (merci aux gens de la production d’avoir réalisé un plan d’extraction aussi rapidement ! – oui, car même moi je n’ai pas accès directement aux données de SPAR, c’est un privilège très rare), il faut encore en extraire du conteneur WARC les seuls fichiers qui nous intéressent. On peut extraire tout d’un coup avec Apache Tika et son option -z mais ça génère un flot de données potentiellement très lourdes. On peut donc faire mieux avec un script python qui utilise la bibliothèque warcio (merci à la communauté et à Andy Jackson en particulier de me l’avoir indiquée).

Je ne vais pas vous détailler le fonctionnement de ce script parce que je l’ai déjà fait dans un Jupyter Notebook qui vous permettra de le tester vous-mêmes : vous allez à cette adresse, puis vous cliquez, dans le fichier README.md sur « Launch Binder ». Vous attendez plusieurs dizaines de secondes que ça se lance, et vous verrez apparaître un environnement Jupyter Hub. Cliquez sur le fichier warcio.ipynb dans la colonne de gauche. Vous pouvez lire les explications puis exécuter chaque bloc de code en appuyant sur le bouton « play » dans la barre de commandes horizontale. A chaque fois que vous cliquerez sur « play », la cellule suivante s’exécutera. Normalement, à la fin du processus, un fichier nommé example.warc_0 aura été créé et apparaîtra dans la colonne de gauche. Il correspondra au seul fichier de format text/html qui se trouvait dans le fichier WARC.

Voilà, c’était un billet beaucoup trop long et sans doute assez technique pour une bonne partie d’entre vous – et peut-être trop simple pour les autres – mais j’espère que vous y aurez trouvé des éléments intéressants. N’hésitez vraiment pas à commenter, les suggestions et réactions me sont très utiles et toujours encourageantes !

Bonne semaine à vous tou·te·s !

1Si vous voulez vous rendre compte de ce à quoi ressemblent ces en-têtes, vous pouvez vous rendre sur un site de test comme celui-ci et entrer l’URL d’un site pour voir ce qu’il renvoie comme en-tête. Les aficionados de la ligne de commande savent déjà sans doute qu’on peut faire de même avec l’outil curl et l’option -I pour ne récupérer que l’en-tête.