Выпуск номера COBOL COMP-3
У меня есть дамп cobol "формат ленты", который имеет смесь текстовых и числовых полей. Я читаю файл в C# как двоичный массив (массив байтов). У меня есть тетрадь, и форматы отлично выстраиваются по текстовым полям. Есть также ряд полей COMP-3. Данные в этих полях не соответствуют ни одному из форматов BCD. Я знаю, какими должны быть данные, и у меня есть необработанные байты COMP-3. Сначала я попытался перейти на EBCDIC, который не дал лучших результатов. Любые мысли о том, как номер COMP-3 может быть сохранен для внутреннего хранения? Ниже приведены три примера PIC, необработанные данные и ожидаемое количество. Я знаю, что у меня правильные положения полей, потому что по обе стороны от чисел есть альфа-данные, и все они выстроены правильно.
Первый пример: PIC поля - 9(9) COMP-3. Данные имеют 5 байтов, шестнадцатеричные значения - 02 01 20 91 22. Полученные данные должны быть датой (00CCYYMMDD). Эта конкретная дата должна быть 3-17-14.
Второй пример: PIC поля - S9(3) COMP-3. Имеется 2 байта данных, шестнадцатеричные значения - 0A. 14 Результирующее значение должно быть между 900 и 999. Насколько я понимаю, "S" означает, что последний клев должен быть 0xC или 0xD, чтобы указать + или -
Третий пример: PIC поля: S9(15)V99 COMP-3 Данные имеют 9 байтов, шестнадцатеричные значения - 00 00 00 00 00 00 01 80 0C Полученное значение должно быть 12,00
Хорошо, так что спасибо людям, которые ответили, они указали мне в правильном направлении. Это действительно проблема представления ASCII/EBCDIC. BCD хранится в EBCDIC. Использование таблицы преобразования ASCII в EBCDIC дает правильно отформатированные цифры BCD:
Я использовал эту ссылку для сопоставления данных: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php
Мои данные: 0A 14 Конвертировано: 25 3C (получается, что 253 является допустимым значением, спецификация была неправильной) C = +, все хорошо
Мои данные: 01 80 0C (исключая начальные нули). Конвертировано: 01 20 0C 12.00 C = +, подразумевается 2 цифры в формате, все хорошо
Мои данные: 02 01 20 91 22 Конвертировано: 02 01 40 31 7F 2014/03/17 (F - неиспользованный клев), все хорошо
5 ответов
Хорошо, так что спасибо обоим людям, которые ответили, когда они указали мне в правильном направлении. Это действительно проблема представления ASCII/EBCDIC. BCD хранится в EBCDIC. Использование таблицы преобразования ASCII в EBCDIC дает правильно отформатированные цифры BCD:
Я использовал эту ссылку для сопоставления данных: http://shop.alterlinks.com/ascii-table/ascii-ebcdic-us.php
My data: 0A 14
Converted: 25 3C (turns out that 253 is a valid value, spec was wrong) C = +, all good
My data: 01 80 0C (excluding leading zeros)
Converted: 01 20 0C 12.00 C = +, implied 2 digits in format, all good
My data: 02 01 20 91 22
Converted: 02 01 40 31 7F 2014/03/17 (F is unused nibble), all good
Еще раз спасибо за два вышеупомянутых ответа, которые привели меня в правильном направлении.
Там нет такого понятия, как COBOL "tape format"
хотя эта фраза может что-то значить для человека, который дал вам данные.
Ключ к вашей проблеме в том, что вы можете прочитать текст. Соедините это с тегом EBCDIC и вашей ссылкой на C#.
Итак, вы читаете данные, которые изначально являются источниками из мейнфрейма, скорее всего, из мейнфрейма IBM, который использует EBCDIC вместо ASCII.
COBOL не имеет встроенной поддержки BCD.
То, что какая-то добрая душа сделала для вас, это "преобразование" данных из EBCDIC в ASCII. Иначе ты бы даже не узнал "текст".
К сожалению, что это означает для любых двоичных или упакованных десятичных полей или полей с плавающей запятой (вы не увидите большую часть последних, но они являются COMP-1/COMP-2), что "convert" означает "потенциально зашифрованный", потому что покрытие предполагает использование отдельных байтов с простыми байтовыми значениями, тогда как все эти поля имеют обычное кодирование, либо через несколько байтов, либо не-EBCDIC, либо и то и другое.
Итак: COMP-3 PIC 9(9). Как вы говорите, пять байтов. Это без знака, поэтому самый правый nybble будет F (все биты включены). Вы немного отстали от своих позиций из-за занятой позиции знака даже для неподписанного поля.
На мэйнфрейме он содержит значение X'020140317F'
, Только это поле во всей полноте может иметь какое-либо значение относительно его значения. Однако, преобразование EBCDIC в ASCII сделало его X'0201209122'.
Как?
Посмотрите значение EBCDIC X'02'
а также X'01'
, Они не меняются. Посмотрите значение X'40'
Ой, это пробел, измените его на ASCII X'20'
, Посмотрите значение X'31'
, На самом деле ничего особенного там нет, и он превратился во что-то более высокое, чем X'7F'
, но если вы посмотрите на используемую таблицу перевода, я думаю, вы поймете, почему это происходит. X'7F'
двойная кавычка, поэтому меняется на X'22'
,
Другие значения, которые вы показываете, страдают той же проблемой.
Вы должны когда-либо брать данные с мэйнфрейма только в символьном формате. Здесь есть много ответов, вы должны посмотреть на related
направо.
Посмотрите на этот недавний вопрос: преобразуйте упакованные десятичные дроби COMP и COMP-3 в читаемое значение с помощью C
Я немного опаздываю, но у меня есть пара предложений, которые могут сделать вашу жизнь проще...
Во-первых, посмотрите, можете ли вы получить ваши компоненты мэйнфрейма для преобразования всех не символьных (то есть двоичных чисел и упакованных десятичных) данных в формат отображения (например, PIC X) перед загрузкой. Тогда вам нужно только иметь дело с "печатаемым" диапазоном числовых символов, представляющих от 0 до 9. Преобразования кодовых страниц только для печатных символов являются достаточно стандартными и, как правило, не приводят к серьезным ошибкам. Переформатирование данных с использованием тетради не представляет трудностей для тех, кто разбирается в среде мэйнфреймов. К сожалению, иногда вы получаете "обходной путь" и утверждается, что он чрезвычайно дорогой, или требует специального программного обеспечения, или любого из ста других фиктивных оправданий.
Если вы получаете "обход", то следующая лучшая вещь - это загрузить файл в двоичном формате и выполнить преобразование собственной кодовой страницы для символьных данных (довольно просто). Далее разберитесь с двоичными данными на основе ваших определений тетради. С помощью нескольких Google вы сможете найти достаточно информации для преобразования данных PACKED-DECIMAL (COMP-3) во все, что вам нужно.
Вот несколько ссылок, с которых можно начать:
Я не рекомендую пытаться перепроектировать преобразования кодовых страниц, применяемые вашим пакетом передачи файлов, чтобы декодировать упакованные десятичные и другие двоичные данные.
Хорошо, давайте посмотрим на ваш первый пример. Учитывая формат и значение, исходный BCD-контент должен был выглядеть примерно так:
02 01 40 31 7F
При преобразовании этого из EBCDIC в ASCII у нас возникают проблемы с первым, вторым и четвертым байтами, потому что они являются управляющими символами - поэтому здесь нам потребуются некоторые подробности о том, как работает ASCII->EBCDIC-конвертер. Глядя на два оставшихся байта, они будут изменены
EBCDIC ASCII CHARACTER
40 -> 20 (blank)
7F -> 22 "
Таким образом, предполагая, что первые два байта остаются неизменными, а третий преобразуется как 31->91
мы заканчиваем с
02 01 20 91 22
что ты и получил. Таким образом, похоже, что произошла какая-то EBCDIC->ASCII-конвертация. В этом случае может случиться так, что вы не сможете восстановить данные, поскольку преобразование может быть не единичным и, следовательно, необратимым.
Глядя на второй пример и используя
EBCDIC ASCII CHARACTER
25 -> 0A (LF)
3C -> 14 (DC4)
ты бы начал с 25 3C
который будет соответствовать формату, но не диапазону, который вы дали.
В третьем примере оригинал 01 20 0C
может быть преобразован в 01 80 0C
поскольку 20
также является управляющим символом EBCDIC без прямого ASCII-эквивалента.
Но, учитывая все другие примеры, я предположил бы, что есть некоторая проблема преобразования кодовой страницы. Если вы использовали какой-либо перенос файла для перемещения данных из (предполагаемого) мэйнфрейма, убедитесь, что он установлен в двоичный режим, и не выполняйте никакого преобразования символов, прежде чем разбивать файл на поля и знать, что такое символ и что "нет.
РЕДАКТИРОВАТЬ: Вы можете найти список нескольких кодовых страниц на основе EBCDIC и ASCII здесь или искать здесь так же, как один PDF.
Вы можете избежать вышеуказанных проблем, преобразовав данные в современный метод передачи данных: XML.