Как декодировать бесконечную длину, заканчивающуюся двумя нулевыми байтами - PullRequest
2 голосов
/ 17 марта 2012

Я декодирую массив байтов в формате TLV (Tag-Length-Value). Иногда Length из Value бесконечно. т.е. я должен читать последующие байты, пока не доберусь до двух последовательных нулевых байтов , означающих конец Value. Проблема в том, что Value TLV само по себе строится из другого TLV с бесконечным Length. Я пытаюсь найти лучший способ декодировать такие TLV с вложенными бесконечными значениями.

В следующем примере каждый квадрат указывает один байт. После прочтения L1 я понимаю, что длина V1 бесконечна, что означает, что я должен читать последующие байты, пока не доберусь до двух нулевых байтов. Но первые два нулевых байта после L1 указывают на конец V3, а не V1:

                                V3                            
                                .                             
                                |             end of V2       
                                \            -----------
+----+----+----+----+----+----+----+----+----+----+----+----+----+
| T1 | L1 | T2 | L2 | T3 | L3 | 13 | 0  | 0  | 0  | 0  | 0  | 0  |
+----+----/----+----/----+----/----+----+----+----+----+----+----+
          |         |         |    -----------         -----------
          |         |         |    end of V3           end of V1
          \         |         |
    V1 Starts here  |         |
                    |         |
                    \         |
              V2 Starts here  |
                              |
                              \
                        V3 starts here 

Мне нужен метод / алгоритм для определения конца V1. Любой совет будет оценен!

Ответы [ 3 ]

3 голосов
/ 17 марта 2012

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

Кроме того, вы можете отслеживать уровень вложенности целым числом: увеличивать каждый раз, когда вы начинаете читать новый TLV, уменьшать его, когда он находит двойной ноль.Чтение заканчивается, когда уровень вложенности снова становится равным нулю.

2 голосов
/ 17 марта 2012

Возможно, вы захотите использовать алгоритм сопоставления скобок со следующим:

  • Любые два нуля являются закрывающими скобками
  • Первые 2 байта или любые два ненулевых байта после двухнули - открывающая скобка.

В конце вы можете построить дерево, в котором каждый тег, заключенный непосредственно (с одним уровнем содержания), является его дочерним.Учитывая эти метаданные, вы можете делать все, что вам нужно ...

2 голосов
/ 17 марта 2012
  1. Если кодируемое вами значение бесконечно, увеличивайте счетчик (который начинается с 1) каждый раз, когда вы сталкиваетесь с другой бесконечной (вложенной) длиной.
  2. Когда вы достигнете двух нулей, уменьшите это значение.
  3. Когда ваш счетчик равен нулю, у вас есть последний индекс значения.

Конечно, это работает, только если внутренние вложенные значения заканчиваются перед внешними (как в вашем примере). Если это не так, я не думаю, что вы можете различить, что заканчивается первым без дополнительной информации о кодировке.

...