Как найти определенный байт во многих байтах? - PullRequest
0 голосов
/ 05 мая 2019

Я прочитал файл, используя Java и использую HexDump для вывода данных.Это выглядит так: Первая и вторая строка: одна: 31 30 30 31 30 30 30 31 31 30 30 31 30 31 31 31 две: 30 31 31 30 30 31 31 30 31 31 30 30 31 31 30 31 Я хочуРаспечатайте данные между первым «31 30 30 31» и вторым «31 30 30 31». Мой идеальный выходной сигнал - 31 30 30 31 30 30 30 31 31 30 30 31 30 31 31 31 30 31. Но реальный вывод неверный, Я думаю, мой код не может найти 31 30 30 31 в data1.Как это выяснить?

Я использую jdk 1.7, и программное обеспечение является идеей

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.File;
public class TestDemo{

  public static void main(String[] args) {


        try {
            File file = new File("/0testData/1.bin");
            DataInputStream isr = new DataInputStream(newFileInputStream(file));

            int bytesPerLine = 16;

            int byteCount = 0;
            int data;
            while ((data = isr.read()) != -1) {
                if (byteCount == 0)
                    System.out.println();
                else if (byteCount % bytesPerLine == 0)
                    System.out.printf("\n",byteCount );
                else
                    System.out.print(" ");


                String data1 = String.format("%02X",data & 0xFF);
                System.out.printf(data1);


                byteCount += 1;
                if(data1.contains("31 30 30 31")) {
                    int i=data1.indexOf("31 30 30 31",12);

                    System.out.println("find it!");
                    String strEFG=data1.substring(i,i+53);
                    System.out.println("str="+strEFG);
                }else {
                    System.out.println("cannot find it");
                }

            }

        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }

    }
}


Мой идеальный выходэто 31 30 30 31 30 30 30 31 31 30 30 31 30 31 31 31 30 31. Но реальный результат:

31 не может найти его 30 не может найти его 30 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его30 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его

30 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 30это 31 не может найти это 31 не может найти это 30cне может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 31 не может найти его

31 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 30 не может найти егоон не может найти его 30 не может найти его 30 не может найти его 31 не может найти его 30 не может найти его 31 не может найти его 30 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его

31 не может найти его 31 не может найти его 30 не может найти его 31 не может найти его 31 не может его найтинайти его 31 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 30 не может найти его 31 не может найти его 31 не может найти его 31 не может его найти

30 не сможет найти его 31 не сможет найти его 31 не сможет его найти30 не может найти его 30 не может найти его 31 не может найти его 31 не может найти его 30 не может найти его 30 не может найти его 30 не может найти его 30 не может найти его 30 не может найти его

1 Ответ

0 голосов
/ 06 мая 2019

Я чувствую, что ваши входные данные немного сбивают с толку. Тем не менее, это, вероятно, отвечает на ваш вопрос.

Он не дает того же вывода, который вы запрашиваете, но я думаю, что вы должны иметь возможность настроить его, чтобы включить или выключить вывод, используя флаг "inPattern". Если inPattern имеет значение true, распечатайте данные, прочитанные из файла, если false, не распечатывайте данные, прочитанные из файла.

Это, вероятно, не самая лучшая форма кодирования, так как это полностью статические методы - но она делает то, что вы просите.

Проблема с вашим кодом (я думаю) состоит в том, что data1 будет строкой из 2 символов. Он не может содержать строку из 11 символов («31 30 30 31»). Если вы попытались сторнировать тест (т. Е. «31 30 30 31» .contains (data1)), тогда он будет соответствовать только одному байту, а не 4 байтам, которые вы намереваетесь найти.

package hexdump;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.LinkedList;

public class HexDumpWithFilter {
//    private static final int beginPattern [] = { 0x47, 0x0d, 0x0a, 0x1a };
    private static final int beginPattern [] = { 0x00, 0x83, 0x7d, 0x8a };
    private static final int endPattern [] = { 0x23, 0x01, 0x78, 0xa5 };
    private static LinkedList<Integer> bytesRead = new LinkedList();

    public static void main(String[] args) {
        try {
            InputStream isr = new DataInputStream(new FileInputStream("C:\\Temp\\resistor.png"));
            int bytesPerLine = 16;
            int byteCount = 0;
            int data;
            boolean inPattern = false;
            while ((data = isr.read()) != -1) {
                // Capture the data just read into an input buffer.
                bytesRead.add(data);
                // If we have too much data in the input buffer to compare to our
                // pattern, peel off the first byte.
                // Note: This assumes that the begin pattern and end Pattern are the same lengths.
                if (bytesRead.size() > beginPattern.length) {
                    bytesRead.removeFirst();
                }

                // Output a byte count at the start of each new line of output.
                if (byteCount % bytesPerLine == 0)
                    System.out.printf("\n%04x:", byteCount);

                // Output the spacing - if we have found our pattern, then also output an asterisk
                System.out.printf(inPattern ? " *%02x" : "  %02x", data);

                // Finally check to see if we have found our pattern if we have enough bytes
                // in our bytesRead buffer.
                if (bytesRead.size() == beginPattern.length) {
                    // If we are not currently in a pattern, then check for the begin pattern
                    if (!inPattern && checkPattern(beginPattern, bytesRead)) {
                        inPattern = true;
                    }
                    // if we are currently in a pattern, then check for the end pattern.
                    if (inPattern && checkPattern (endPattern, bytesRead)) {
                        inPattern = false;
                    }
                }

                byteCount += 1;
            }
            System.out.println();
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        }
    }

    /**
     * Function to check whether our input buffer read from the file matches
     * the supplied pattern.
     * @param pattern the pattern to look for in the buffer.
     * @param bytesRead the buffer of bytes read from the file.
     * @return true if pattern and bytesRead have the same content.
     */
    private static boolean checkPattern (int [] pattern, LinkedList<Integer> bytesRead) {
        int ptr = 0;
        boolean patternMatch = true;
        for (int br : bytesRead) {
            if (br != pattern[ptr++]) {
                patternMatch = false;
                break;
            }
        }
        return patternMatch;
    }
}

Существует небольшая проблема с этим кодом в том, что он не отмечает начальный шаблон, но отмечает конечный шаблон. Надеюсь, это не проблема для вас. Если вам нужно правильно пометить начало или не отметить окончание, тогда будет другой уровень сложности. По сути, вам придется читать вперед в файле и записывать данные на 4 байта за данными, которые вы читали. Этого можно достичь, напечатав значение, которое выходит из буфера, в строке, которая гласит:

    bytesRead.removeFirst();

вместо печати значения, считанного из файла (то есть значения в переменной «data»).

Ниже приведен пример данных, полученных при работе с файлом PNG изображения резистора.

0000:  89  50  4e  47  0d  0a  1a  0a  00  00  00  0d  49  48  44  52
0010:  00  00  00  60  00  00  00  1b  08  06  00  00  00  83  7d  8a
0020: *3a *00 *00 *00 *09 *70 *48 *59 *73 *00 *00 *2e *23 *00 *00 *2e
0030: *23 *01 *78 *a5  3f  76  00  00  00  07  74  49  4d  45  07  e3
0040:  03  0e  17  1a  0f  c2  80  9c  d0  00  00  01  09  49  44  41
0050:  54  68  de  ed  9a  31  0b  82  40  18  86  cf  52  d4  a1  7e
0060:  45  4e  81  5b  a3  9b  10  ae  ae  4d  4d  61  7f  a1  21  1b
0070:  fa  0b  45  53  53  ab  ab  04  6e  42  4b  9b  d0  64  bf  a2
0080:  06  15  a9  6b  ef  14  82  ea  ec  e8  7d  c6  f7  0e  f1  be
0090:  e7  3b  0f  0e  25  4a  29  25  a0  31  5a  28  01  04  fc  35
00a0:  f2  73  e0  af  af  b5  93  fd  c9  8c  cd  36  cb  da  f9  ae
00b0:  ad  11  d3  50  84  2e  50  92  96  24  88  f2  ca  b1  41  7b
00c0:  cc  64  c7  db  b6  be  7e  5e  87  ef  0e  08  e3  82  64  85
00d0:  b8  47  4c  56  50  12  c6  85  b8  9f  20  1e  0b  10  bd  81
00e0:  64  1e  5b  38  49  cb  ca  31  e3  7c  67  b2  b4  c7  f6  c4
00f0:  62  da  65  b2  f9  ea  c2  64  a7  dd  90  c9  fa  a3  3d  0e
0100:  61  00  01  10  00  20  00  02  00  04  40  00  80  00  08  00
0110:  10  00  01  00  02  7e  82  af  5f  c6  99  86  42  5c  5b  7b
0120:  eb  19  be  f7  e2  8d  a4  77  f8  e8  bb  07  51  5e  7b  91
0130:  28  c4  0e  d0  55  89  38  96  2a  6c  77  3a  96  4a  74  55
0140:  12  57  00  8f  05  88  de  40  12  fe  8a  c0  21  0c  01  00
0150:  02  20  00  34  c3  03  f7  3f  46  9a  04  49  f8  9d  00  00
0160:  00  00  49  45  4e  44  ae  42  60  82

Заметьте, что перед некоторыми байтами стоит звездочка? Это байты, которые находятся внутри beginPattern и endPattern.

Также обратите внимание, что я использовал beginPattern и endPattern. Вам не нужно этого делать, я сделал это только для того, чтобы мне было легче найти шаблон в моем файле resistor.png для проверки соответствия шаблону. Вы можете использовать одну переменную для начала и конца, установить одно и то же значение для обоих или просто назначить endPattern = beginPattern, если вы хотите использовать один шаблон (например, «0x31, 0x30, 0x30, 0x31») для начала и конца.

...