COBOL COMP-3数字格式问题

时间:2014-04-02 13:17:58

标签: format cobol bcd ebcdic comp-3

我有一个cobol"磁带格式"具有文本和数字字段混合的转储。我在C#中读取文件作为二进制数组(字节数组)。我有复印本,格式在文本字段排列很好。还有许多COMP-3领域。这些字段中的数据似乎与任何BCD格式都不匹配。我知道数据应该是什么,我有COMP-3的原始字节。我尝试首先转换为EBCDIC,但没有取得更好的结果。有关如何在内部存储COMP-3号码的任何想法?以下是PIC的三个示例,原始数据和预期数量。我知道我的字段位置是正确的,因为数字的两边都有alpha数据,而且所有字符都正确排列。

第一个例子: 该场的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 个答案:

答案 0 :(得分:3)

没有COBOL "tape format"之类的东西,尽管这句话可能对提供数据的人有意义。

您的问题的线索是您可以阅读文本。将其连接到EBCDIC标记和您对C#的引用。

因此,您正在读取的数据最初源自大型机,很可能是IBM大型机,它使用EBCDIC而不是ASCII。

COBOL没有对BCD的原生支持。

灵魂为你做的是将数据从EBCDIC“转换”为ASCII。否则你甚至不会识别“文字”。

不幸的是,对于任何二进制或压缩十进制或浮点字段(你不会看到最后一个,但它们是COMP-1 / COMP-2)的意思是“转换”意味着“潜在的” “scrambled”,因为coversion是假定单个字节,具有简单的字节值,而所有这些字段都有传统的编码,可以通过多个字节或非EBCDIC值或两者兼而有之。

所以:COMP-3 PIC 9(9)。如你所说,五个字节。它是无符号的,因此最右边的nybble将是F(所有位都打开)。由于符号位置被占用,您的位置稍微偏离,即使对于无符号字段也是如此。

在大型机上,它包含值X'020140317F'。只有整个领域才能对其价值产生任何意义。但是,EBCDIC到ASCII的转换使其成为X'0201209122'。

如何?

查找X'02'X'01'的EBCDIC值。他们不会改变。查找X'40'的值,哎呀,这是一个空格,将其更改为ASCII X'20'。查找X'31'的值。实际上没什么特别的,它已转换为高于X'7F'的东西,但是如果你看一下使用的翻译表,我想你会明白为什么会发生这种情况。 X'7F'是双引号,因此更改为X'22'

您展示的其他值会遇到同样的问题。

您应该只以纯字符格式从大型机中获取数据。这里有很多答案,你应该看看右边的related

看看最近的这个问题:Convert COMP and COMP-3 Packed Decimal into readable value with C

答案 1 :(得分:2)

好的,让我们来看看你的第一个例子。鉴于原始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也是一个没有直接ASCII等效的EBCDIC控制字符。

但是考虑到所有其他示例,我会假设存在一些代码页转换问题。 如果您使用某种文件传输方式从(假设的)大型机移动数据,请确保将其设置为二进制模式,并且在将文件拆分为字段之前不要进行任何字符转换,并知道' s意味着是一个角色而不是。

编辑:您可以找到几个基于EBCDIC和ASCII的代码页的列表here,或者查看here与一个pdf相同的内容。

答案 2 :(得分:1)

我有点迟到了,但有一些建议可能会让你的生活更轻松......

首先,看看你是否可以让你的大型机conterparts转换所有非字符(即二进制数字和压缩十进制)数据 在您之前显示格式(例如PIC X) 下载它。然后你只需要处理"可打印"表示0到9的数字字符范围。可打印字符 只有代码页转换是相当标准的,并且往往不会搞砸。重新格式化给定字帖的数据不是 任何人都难以接近 精通大型机环境。不幸的是,有时你会得到" runaround"并声称它是 非常昂贵的,或采取特殊软件,或任何其他一百个虚假的借口。

如果你得到"套路"然后,下一个最好的事情是以二进制格式下载文件并进行自己的代码页转换 对于角色数据(公平地说 直截了当)。接下来根据您的字帖定义处理二进制数据。有几个谷歌你应该能找到 足够的信息可以将PACKED-DECIMAL(COMP-3)数据转换为您需要的任何数据。

以下是一些可以帮助您入门的链接:

Numeric Data Formats

Packed Decimal

我建议您不要尝试对文件传输包应用的代码页转换进行反向工程 解码压缩十进制和其他二进制数据。

答案 3 :(得分:0)

好的,感谢两位回应的人,他们指出了我正确的方向。这确实是一个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

再次感谢上述两个答案,这些答案使我朝着正确的方向前进。

答案 4 :(得分:0)

通过将数据转换为传输数据的现代方法,可以避免上述问题:XML。