Преобразование символов EBCDIC в значения Hex (данные AFP EBCDIC)

Я работаю с некоторыми данными EBCDIC, которые мне нужно проанализировать и найти некоторые значения Hex. Проблема, с которой я столкнулся, заключается в том, что, похоже, я читаю файл с неправильной кодировкой. Я вижу, что моя запись начинается с «!» (что является x5A в EBCDIC), но при преобразовании в шестнадцатеричный формат возвращается как x21, что является значением ASCII для «!».

Я надеялся, что во фреймворке есть встроенный метод, но боюсь, что мне придется создать собственный класс для правильного сопоставления набора символов EBCDIC.

Using fileInStream As New FileStream(inputFile, FileMode.Open, FileAccess.Read)
   Using bufferedInStream As New BufferedStream(fileInStream)
      Using reader As New StreamReader(bufferedInStream, Encoding.GetEncoding(37))
         While Not reader.EndOfStream
            Do While reader.Peek() >= 0
               Dim charArray(52) As Char
               reader.Read(charArray, 0, charArray.Length)

               For Each letter As Char In charArray
                  Dim value As Integer = Convert.ToInt16(letter)

                  Dim hexOut As String = [String].Format("{0:x}", value)
                  Debug.WriteLine(hexOut)
               Next
            Loop
         End While
      End Using
   End Using
End Using

Спасибо!


person Tom Alderman    schedule 13.04.2009    source источник


Ответы (3)


Да, когда вы читаете текстовые данные в виде строк, они сохраняют их внутри как Unicode. Если вам важны двоичные значения (т.е. необработанные байты), не декодируйте их в первую очередь.

Если вам действительно нужно что-то сделать с пользовательской кодировкой EBCDIC, вы можете использовать мою реализацию EBCDIC с открытым исходным кодом - но я думаю, вам просто нужно решить, рассматриваете ли вы это как двоичные данные или как текст.

person Jon Skeet    schedule 13.04.2009

Сделать это можно так:

  1. Откройте файл AFP. Прочтите первые 9 байтов.
  2. Байт 0 должен быть 0xD3 или 0x5A. Байт 1 и байт 2 будут длиной SFI, включая 8 из 9 байтов, которые вы только что прочитали. Это big endian, поэтому длина = byte1 * 256 + byte2.
  3. Байты 3, 4 и 5 - это идентификатор структурированного поля. Если вам нужен текст для печати, ищите PTX, (элемент текста презентации) 0xD3 0xEE 0x9B. Пропустите длину 8 и прочтите следующие 9 байтов, если вы не нашли их.
  4. Если вы все же нашли PTX, прочтите длину 8 байт. Анализ управляющих последовательностей, чтобы добраться до текста, немного сложен. Первый будет начинаться с 0x2b 0xD3, байта для длины и байта для типа управляющей последовательности. Если этот байт является нечетным числом, следующая управляющая последовательность будет опускать заголовок 0x2B 0xD3, вместо этого начиная с байта длины. Это называется «цепочкой» и, по-видимому, было введено, чтобы заставить программистов безумно разбираться в этом материале.
  5. Пропустите вперед от длины байта length-1 и нажмите или просто найдите следующий 0x2B 0xD3; последняя последовательность управления не будет связана, и все, что следует до конца PTX, будет EBCDIC. Воспользуйтесь библиотекой Джона Скита (спасибо, Джон) и найдите следующий элемент PTX.

Извините, я был многословен. Это выполнимо, но не просто.

person R Ubben    schedule 14.04.2009

Будьте осторожны, читая данные AFP таким образом. Это обратный порядок байтов и в байтовом, и в битовом порядке. Вам нужно будет это учитывать, если вы обрабатываете их как двоичные данные, например, при синтаксическом анализе через структурированные поля в документе.

person R Ubben    schedule 13.04.2009
comment
Я пытаюсь получить данные структурированных полей. Спасибо за вклад - person Tom Alderman; 14.04.2009