Как правильно проверить заголовок PNG в java?

#java #validation #header #png

#java #валидация #заголовок #png

Вопрос:

Я пытаюсь написать функцию, которая проверит, не поврежден ли PNG-файл. Здесь я нашел функцию, также представленную ниже, которая сохраняет байты файла в свой собственный байтовый массив. Я знаю, что первые восемь байтов файла PNG всегда содержат одни и те же десятичные значения 137 80 78 71 13 10 26 10 (шестнадцатеричное: 89 50 4e 47 0d 0a 1a 0a). Когда я печатаю контекст массива байтов, который начинается с -1-40-1-3201674707370011007207200-1-370-124022222232235333565555686666681088888810101010101 ... , а затем преобразую его в десятичные значения, я не вижу магическое число в начале. Пожалуйста, что я неправильно понял? Я хотел бы прочитать изображение и сравнить его заголовок либо с десятичными, либо с шестнадцатеричными значениями.

 public static void main(String[] args)
    {

        File file = new File("src/resources/dog.png");

        readContentIntoByteArray(file);
    }
 
  private static byte[] readContentIntoByteArray(File file)
    {
        FileInputStream fileInputStream = null;
        byte[] bFile = new byte[(int) file.length()];
        try
        {
            //convert file into array of bytes
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(bFile);
            fileInputStream.close();
            for (int i = 0; i < bFile.length; i  )
            {
                System.out.print((char) bFile[i]);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return bFile;
    }
 

Комментарии:

1. К вашему сведению: Чтобы прочитать весь файл в a byte[] , используйте byte[] bFile = Files.readAllBytes(Paths.get("dog.png"))

2. «что я неправильно понял?» Как печатать байты. Чтобы напечатать байт в шестнадцатеричной форме, используйте printf("x ", bFile[i]) . Чтобы напечатать байт в десятичной форме, используйте printf("%d ", bFile[i]) или print(bFile[i] " ") .

3. @Andreas действительно, я забыл указать тип при печати. Спасибо, что напомнили мне.

Ответ №1:

Вы печатаете фактические байты в виде символов на терминале, а не представление этих байтов в десятичном или шестнадцатеричном виде, как говорит @Andreas.

Вы можете проверить заголовок с помощью:

         byte[] data = readContentIntoByteArray(file);
        byte[] expected = new byte[] {-119, 80, 78, 71, 13, 10, 26, 10};
        for (int i = 0; i < expected.length; i  ) {
            if (expected[i] != data[i]) {
                System.out.println("mismatch at "   i);
            }
        }
 

Комментарии:

1. Большое вам спасибо. Такого рода проверка — это то, что я пытался реализовать. Позже я узнал, что мой «dog.png», несмотря на то, что он имеет расширение png, его заголовок выглядит так ff d8 ff e0-00 10 4a 46-49 46 00 01-01 00 00 48 , а 89 50 4e 47-0d 0a 1a 0a-00 00 00 0d-49 48 44 52 не, и это то, что меня больше всего смущает, как это вообще возможно, при этом не искажается и отлично отображает изображение.