Tableau des préfixes
Chaque ligne a été vérifiée en encodant les vrais octets magiques du format. Le « préfixe stable » est la partie qui ne change jamais pour ce format. Les caractères qui suivent dépendent du reste du fichier.
| Préfixe Base64 | Octets magiques (hex) | Format | Ouvrir avec |
|---|---|---|---|
iVBORw0KGgo | 89 50 4E 47 0D 0A 1A 0A | PNG | Base64 en PNG |
/9j/ | FF D8 FF | JPEG | Base64 en JPG |
R0lGOD | 47 49 46 38 (GIF8) | GIF (R0lGODlh = GIF89a, R0lGODdh = GIF87a) | Base64 en GIF |
UklGR | 52 49 46 46 (RIFF) | WebP, WAV, AVI | Base64 en WebP, Base64 en WAV |
JVBERi0 | 25 50 44 46 2D (%PDF-) | Base64 en PDF | |
UEsDB | 50 4B 03 04 (PK..) | ZIP, DOCX, XLSX, PPTX, JAR, APK, EPUB | Base64 en ZIP, Word, Excel |
H4sI | 1F 8B 08 | gzip | Décoder du Base64 gzip |
eJ, eN, eF, eA | 78 9C, 78 DA, 78 5E, 78 01 | zlib | Zlib et Base64 |
eyJ | 7B 22 ({") | Objet JSON, JWT | Base64 en JSON, décodeur JWT |
PD94bWwg | 3C 3F 78 6D 6C 20 (<?xml ) | XML, SVG avec déclaration | Base64 en XML |
PHN2Zy | 3C 73 76 67 20 (<svg ) | SVG sans déclaration (<svg suivi d’un saut de ligne donne PHN2Zw) | Base64 en SVG |
MII | 30 82 | DER : certificats, clés, CSR | décodeur de certificats |
AAAA | 00 00 00 | Blob de clé publique SSH, ou zéros en tête | empreinte de clé SSH |
SUQz | 49 44 33 (ID3) | MP3 avec balise ID3v2 | Base64 en MP3 |
AAABAA | 00 00 01 00 | ICO | Base64 en ICO |
d09GMg | 77 4F 46 32 00 (wOF2) | Police WOFF2 à contours TrueType (les polices CFF commencent par d09GMk9UVE8) | Base64 en police |
TVqQ | 4D 5A 90 (MZ) | EXE ou DLL Windows (certains éditeurs de liens écrivent MZP, ce qui donne TVpQ) | Base64 en fichier |
f0VMR | 7F 45 4C 46 (.ELF) | Binaire ELF Linux | Base64 en fichier |
Quelques lignes méritent une remarque :
- RIFF est un conteneur. Le nom du format se trouve aux octets 8 à 11, et les octets 9 à 11 s’encodent dans les caractères 13 à 16 :
RUJQpour WebP (EBP),QVZFpour WAV (AVE),Vkkgpour AVI (VI). La première lettre du nom du format partage un groupe de 3 octets avec la taille du fichier : elle ne produit donc pas de caractère stable. - zlib n’a pas de préfixe unique. Le second octet indique le niveau de compression :
eJpour le niveau par défaut,eNpour les niveaux 7 à 9,eFpour 2 à 5,eApour 0 et 1 (tels que les écrit le modulezlibde Python). - JSON ne commence par
eyJque si les deux premiers caractères sont{"sans espace.{ "a": 1 }commence pareyAi, un{formaté suivi d’un saut de ligne commence parewo, et un tableau[commence parW. - Les structures DER commencent par une balise SEQUENCE
30, qui donne toujoursM. Une longueur sur deux octets (30 82) donneMII, et le caractère suivant dépend de la longueur : une clé publique RSA 2048 donneMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA, un certificat typiqueMIIC,MIIDouMIIE. Les structures courtes utilisent une longueur sur un octet : une clé privée Ed25519 commence parMC4C, une clé publique P-256 parMFkw. - Les clés publiques SSH commencent par une longueur big-endian de 4 octets : le blob commence donc par
AAAA. Les caractères suivants épellent le type de clé :AAAAC3NzaC1lZDI1NTE5correspond àssh-ed25519,AAAAB3NzaC1yc2Eàssh-rsa,AAAAE2VjZHNhàecdsa. En dehors de SSH, une suite deAsignifie des octets nuls. - Les fichiers MP3 sans balise ID3 commencent directement par un en-tête de trame. Ses bits de synchronisation
FF Fxdonnent un//en tête, par exemple//uQpourFF FB 90. - Base64URL remplace
+et/, et le préfixe JPEG devient donc_9j_. Les autres préfixes du tableau ne contiennent aucun de ces caractères et sont identiques dans les deux alphabets.
Pourquoi le préfixe est stable
Base64 travaille par groupes de 3 octets. Chaque groupe de 3 octets devient exactement 4 caractères, et ces 4 caractères ne dépendent que de ces 3 octets. Rien de ce qui vient plus loin dans le fichier ne rejaillit en arrière. Si un format commence toujours par les mêmes 3 octets, son Base64 commence donc toujours par les mêmes 4 caractères.
bytes: FF D8 FF
bits: 11111111 11011000 11111111
groups: 111111 111101 100011 111111
index: 63 61 35 63
chars: / 9 j /
Quand la signature fixe ne fait pas un multiple de 3 octets, le dernier groupe mélange des bits connus avec des bits du reste du fichier. Prenons %PDF- et ses 5 octets. Les 3 premiers octets donnent 4 caractères stables (JVBE). Les 2 suivants en donnent 2 de plus (Ri), et le septième caractère mélange les 4 derniers bits de - avec les 2 premiers bits du chiffre de version. Tout chiffre commence par les bits 00 : en pratique, ce caractère vaut donc toujours 0. Après JVBERi0, la version transparaît : JVBERi0xLjQ correspond à %PDF-1.4, JVBERi0xLjc à %PDF-1.7, JVBERi0yLjA à %PDF-2.0.
La signature PNG fait 8 octets, ce qui donne 10 caractères stables. Le onzième mélange le dernier octet de la signature avec le premier octet de la longueur du bloc IHDR, qui vaut toujours 0 : iVBORw0KGgo tient donc. Comme tout PNG continue avec ce bloc IHDR, les vrais PNG partagent un préfixe encore plus long : iVBORw0KGgoAAAANSUhEUg.
Quand le préfixe se décale
Le préfixe ne fonctionne que si les octets magiques se trouvent à la position 0, 3, 6, etc. Ajoutez un octet devant et tous les groupes se décalent : les caractères changent complètement.
| Entrée | Le Base64 commence par |
|---|---|
| Signature PNG | iVBORw0KGgoAAAA |
| 1 octet + signature PNG | AIlQTkcNChoKAAAA |
| 2 octets + signature PNG | AACJUE5HDQoaCgAA |
| 3 octets + signature PNG | AAAAiVBORw0KGgoA |
Avec 3 octets de plus, l’alignement est rétabli et le préfixe familier réapparaît 4 caractères plus loin. Causes fréquentes d’un préfixe décalé ou absent :
- Une marque d’ordre des octets (BOM). Du texte UTF-8 avec BOM commence par
77u/(EF BB BF). Le BOM fait 3 octets : du JSON placé après montre donc toujourseyJ, soit77u/eyJ…. Du texte UTF-16 avec BOM commence par//4ou//5(little-endian) ou par/v8(big-endian). - Du texte UTF-16. Du texte enregistré en UTF-16LE place un octet nul après chaque caractère ASCII, ce qui produit beaucoup de
A:HellodevientSABlAGwAbABvAA==. Le-EncodedCommandde PowerShell ressemble à cela. Utilisez le décodeur PowerShell ou Base64 en UTF-16. - Une compression ou un chiffrement. Un PNG compressé en gzip commence par
H4sI; un fichier chiffré n’a aucun préfixe reconnaissable. - Une data URI.
data:image/png;base64,est un en-tête ; le Base64 commence après la virgule. L’analyseur de data URI sépare les deux pour vous. - Des sauts de ligne et des espaces. Ils ne décalent pas les octets, mais une recherche de préfixe avec
startswithéchouera si la chaîne commence par un saut de ligne ou un guillemet. Nettoyez d’abord, ou passez-la dans Réparer du Base64.
Vérifier un préfixe dans le code
Vous pouvez comparer les premiers caractères comme des chaînes, mais comparer les octets décodés est moins sujet aux erreurs : les nombres magiques viennent directement de la spécification de chaque format, et vous n’avez jamais à calculer quels caractères sont stables. Décoder seulement les 12 premiers caractères donne les 9 premiers octets, ce qui suffit pour la plupart des signatures :
import base64
SIGNATURES = {
b"\x89PNG\r\n\x1a\n": "png",
b"\xff\xd8\xff": "jpeg",
b"%PDF-": "pdf",
b"PK\x03\x04": "zip",
b"\x1f\x8b": "gzip",
}
def sniff(b64: str) -> str:
head = base64.b64decode(b64.strip()[:12])
for magic, name in SIGNATURES.items():
if head.startswith(magic):
return name
return "unknown"
print(sniff("iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB")) # png
print(sniff("JVBERi0xLjcKJcfsj6IK")) # pdf
L’outil Base64 en fichier fait la même vérification avec une liste plus longue et affiche un aperçu quand le navigateur sait afficher le format. Pour voir comment les groupes de 6 bits correspondent aux caractères, consultez le fonctionnement de Base64 et la table de l’alphabet.
FAQ
Que signifie une chaîne Base64 qui commence par iVBORw0KGgo ?
C’est une image PNG. iVBORw0KGgo est la forme Base64 de la signature PNG de 8 octets 89 50 4E 47 0D 0A 1A 0A. Collez-la dans Base64 en PNG pour la voir.
Qu'est-ce que /9j/ au début d'une chaîne Base64 ?
Un JPEG. Les octets FF D8 FF qui ouvrent tout fichier JPEG s’encodent en /9j/. En Base64URL, le même préfixe s’écrit _9j_.
Pourquoi les JWT commencent-ils toujours par eyJ ?
L’en-tête d’un JWT est un objet JSON : il commence donc par {", et ces deux octets s’encodent en eyJ. La partie payload commence par eyJ pour la même raison.
Mon Base64 ne correspond à aucun préfixe connu. Que faire ?
Les données ont peut-être des octets en trop au début, sont compressées ou chiffrées, ou sont du simple texte. L’outil Base64 en fichier décode les données et compare les octets à de nombreuses signatures.