【问题标题】:COBOL COMP-3 number format issueCOBOL COMP-3 数字格式问题
【发布时间】:2014-05-13 19:30:58
【问题描述】:

我有一个混合了文本和数字字段的 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 是未使用的半字节),一切都很好

【问题讨论】:

    标签: format cobol bcd ebcdic comp-3


    【解决方案1】:

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

    【讨论】:

    • 不幸的是,供应商推动了业务发展,实际上是大多数行业,他们并不关心提供翻译。问题和练习的重点是为 EBCDIC 压缩 comp-3 数字找到解决方案,我最终做到了。
    【解决方案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 控制字符。

    但鉴于所有其他示例,我会假设存在一些代码页转换问题。 如果您使用某种文件传输从(假定的)大型机中移动数据,请确保将其设置为二进制模式,并且在将文件拆分为字段并知道什么是字符之前不要进行任何字符转换还有什么。

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

    【讨论】:

    • 正如我所说:X'91' 只是一个假设 - 因为 X'31' 在 EBCDIC 中绝对没有意义,它可能被映射到任何东西。查看我们的终端仿真转换表,它将映射到 X'2D',就像该区域中的大多数其他值一样,但是可能会发生各种奇怪的事情......
    • 可能对社区(和我哈哈)有所帮助的是可用 EBCDIC 代码页及其映射的链接或重新发布。我在网上找到了一些零碎的东西,但没有确定的。很有可能这确实是一台 IBM 大型机。不久前,我为供应商(First Data)做了一些合同工作,IBM 在那里。
    【解决方案3】:

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

    再次感谢以上两个答案,让我朝着正确的方向前进。

    【讨论】:

    • 如上所述,解决方案是使用上面链接中的代码页转换将 EBCDIC 字段转换回 ASCII,然后应用标准 comp-3 映射逻辑。前两个建议将我引向了正确的方向,但它们的翻译都有一些小问题,这使得它们在技术上并不正确,因为它们得出的结论是 EBCDIC 到 ASCII 映射仍然会导致错误的值,这实际上是不正确的。
    【解决方案4】:

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

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

    如果你得到“runaround”,那么下一个最好的办法是以二进制格式下载文件并进行你自己的代码页转换 对于字符数据(相当 直截了当)。接下来根据您的字帖定义处理二进制数据。用几个谷歌你应该能找到 有足够的信息将 PACKED-DECIMAL (COMP-3) 数据转换为您需要的任何数据。

    这里有几个链接可以帮助您入门:

    Numeric Data Formats

    Packed Decimal

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

    【讨论】:

      【解决方案5】:

      没有 COBOL "tape format" 这样的东西,尽管这个短语可能对给你数据的人有意义。

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

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

      COBOL 不支持 BCD。

      某个善良的灵魂为您所做的是将数据从 EBCDIC“转换”为 ASCII。否则你甚至不会识别“文本”。

      不幸的是,对于任何二进制或压缩十进制或浮点字段(您不会看到很多最后的字段,但它们是 COMP-1/COMP-2),这意味着“转换”意味着“可能scrambled”,因为覆盖假设单个字节,具有简单的字节值,而所有这些字段都具有常规编码,通过多个字节或非 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

      【讨论】:

      • 首先感谢大家迄今为止的艰苦工作和详尽的解答。我确实尝试了手动和使用 C# 翻译功能的 EBCDIC 代码页翻译,并遇到了如上所述的类似问题(例如非映射字符)。不幸的是,数据提供者(在本例中为 First Data)不会修改所提供的格式。 “磁带格式”指的是文件的标题,以防万一任何罗斯福的人可能知道这一点。这恰好是格式“20”,其中列出了有关信用卡发卡机构的信用卡费用数据。
      • 很遗憾,该规范是保密的,无法在线发布。但是,它不包含有关存储在哪个 EBCDIC 代码页中的任何线索。我已经向他们发出了另一个调用,看看我是否能弄清楚这一点,但此时听起来这是一个 EBCDIC 翻译问题。跨度>
      • 顺便说一句 - 这是行业使用的标准化(尽管是保密的)格式,所以在某个地方有一些魔法酱可以转换这些加扰的字符。其他人已成功加载此文件,并且此文件是根据已存在数十年的大量文档规范生成的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 2018-10-29
      • 2019-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多