web-dev-qa-db-fra.com

Comment identifier le contenu d'un octet [] est un JPEG?

J'ai un petit tableau d'octets (moins de 25 Ko) que je reçois et décode dans le cadre d'une enveloppe de message plus grande. Parfois, c'est une image, en plus c'est un JPG. Je n'ai aucune information de contexte autre que le tableau d'octets, et je dois identifier les deux si c'est IS une image, et si l'image est de type JPG.

Y a-t-il un nombre magique, ou des octets magiques qui existent au début, à la fin ou à un certain décalage que je peux regarder pour l'identifier?

Un exemple de mon code ressemble à ceci (de mémoire, pas c/p):

byte[] messageBytesAfterDecode = retrieveBytesFromEnvelope();
if(null != messageBytesAfterDecode && messageBytesAfterDecode > 0){
    if(areTheseBytesAJpeg(messageBytesAfterDecode)){
        doSomethingWithAJpeg(messageBytesAfterDecode)
    }else{
        flagEnvelopeAsHavingBadContentInTheField();
    }
}

J'ai vraiment besoin de ce qui irait dans le

areTheseBytesAJpeg(byte[] mBytes){}

ou même un pointeur sur une spécification qui la détaille. J'espère qu'il existe un moyen très rapide de prendre cette décision, car je ne veux pas vraiment les lire dans une image, etc.

31
Kylar

De wikipedia:

Les fichiers d'image JPEG commencent par FF D8 et se terminent par FF D9.

http://en.wikipedia.org/wiki/Magic_number_ (programmation)

53
zsalzbank

Quelques informations supplémentaires sur un autre format de fichier avec jpeg: l'initiale du fichier contient ces octets

BMP : 42 4D
JPG : FF D8 FF EO ( Starting 2 Byte will always be same)
PNG : 89 50 4E 47
GIF : 47 49 46 38

du code:

private static Boolean isJPEG(File filename) throws Exception {
    DataInputStream ins = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
    try {
        if (ins.readInt() == 0xffd8ffe0) {
            return true;
        } else {
            return false;

        }
    } finally {
        ins.close();
    }
}
13
RATHI

Une autre source de "connaissances" sur les nombres magiques (y compris pour les fichiers JPEG) est le fichier magic utilisé par la commande GNU/Linux file.

Si la commande file est installée, alors file --version vous indiquera où se trouve le fichier magic, et vous pouvez le lire à l'aide d'un éditeur de texte ... et une lecture attentive de man 5 magic.

(Et le contenu du fichier magic confirme les détails des autres réponses.)

7
Stephen C

Citant cet article wikipedia :

Les fichiers d'image JPEG commencent par FF D8 et se terminent par FF D9. Les fichiers JPEG/JFIF contiennent le code ASCII pour "JFIF" (4A 46 49 46) sous la forme d'une chaîne terminée par un caractère nul. Les fichiers JPEG/Exif contiennent le code ASCII pour "Exif" (45 78 69 66) également sous la forme d'une chaîne terminée par un caractère nul, suivie de plus de métadonnées sur le fichier.

6
user257111

De nombreux formats sont identifiés par des soi-disant nombres magiques. Il s'agit de séquences d'octets généralement situées au début du fichier pour déterminer si les données binaires suivantes correspondent réellement à ce que vous pensez. Une recherche rapide sur Google a renvoyé: http://www.linfo.org/magic_number.html et plus précisément la citation:

"De même, un nombre magique couramment utilisé pour les fichiers d'images JPEG (Joint Photographic Experts Group) est 0x4A464946, qui est l'équivalent ASCII de JFIF (JPEG File Interchange Format). Cependant, les nombres magiques JPEG sont pas les premiers octets du fichier; ils commencent plutôt par le septième octet. Des exemples supplémentaires incluent 0x4D546864 pour les fichiers MIDI (Musical Instrument Digital Interface)) et 0x425a6831415925 pour les fichiers compressés bzip2. "

4
damg

Un fichier JPG possède un en-tête spécifique que vous pouvez utiliser pour déterminer une très bonne probabilité qu'il s'agisse d'un fichier JPG. Cependant, il n'est pas clair si vous aurez le fichier entier dans le tableau d'octets.

Quoi qu'il en soit, voici les détails sur l'en-tête: http://www.fastgraph.com/help/jpeg_header_format.html

0
Jonathan Wood