如何将 Cobol 响应中的签名显示字段解码为 Java 中的 BigDecimal

Posted

技术标签:

【中文标题】如何将 Cobol 响应中的签名显示字段解码为 Java 中的 BigDecimal【英文标题】:How to decode Signed Display field in Cobol response to BigDecimal in Java 【发布时间】:2020-09-25 20:40:06 【问题描述】:

我正在使用 CopyBook4Java 库,我可以在其中找到无法完全解决我的情况的解码选项,其中大型机签名显示字段为 BigDecimal 类型变量。下面你可以看到我的测试:

assertEquals(new BigDecimal("0.00"), typeConverter.to("00000000000000ä".getBytes(StandardCharsets.ISO_8859_1), 0, 15, 2, true));
assertEquals(new BigDecimal("-200541.00"), typeConverter.to("00000002005410ä".getBytes(StandardCharsets.ISO_8859_1), 0, 15, 2, true));
assertEquals(new BigDecimal("33258.91"), typeConverter.to("00000000332589A".getBytes(StandardCharsets.ISO_8859_1), 0, 15, 2, true));

CopyBookFieldSigningType.LAST_BYTE_EBCDIC_BIT5 让我可以处理响应,但不幸的是解码的值是错误的,尤其是对于:

十进制字段 0.01-0.09 零值 0.00 负值,即-200541.00

我想我需要修改:

(signingType == CopyBookFieldSigningType.LAST_BYTE_EBCDIC_BIT5) 
            byte res = (byte)(bytes[bytes.length -1] & 240); // Read last byte and zero first 4 bits of the result, 11110000
            byte[] bytesCopy = Arrays.copyOf(bytes, bytes.length - 1);
            if((byte)(res ^ 208) == 0 ||(byte)(res ^ 176) == 0)  // 208 = 11010000, 176 = 10110000
                strValue = "-" + getString(bytesCopy, offset, length -1, removePadding, 1) + String.valueOf(bytes[bytes.length -1] & 15);
             else 
                strValue = getString(bytesCopy, offset, bytesCopy.length, removePadding, 1) + String.valueOf(bytes[bytes.length -1] & 15);
            

        

我不知道如何为我的案例正确修改算法。任何人都可以建议我如何将大型机的响应正确解码为BigDecimal 格式吗?

在这里你可以通过单元测试检查我的存储库:https://repl.it/@epredator/copybook4java#copybook4java/src/test/java/com/nordea/oss/copybook/converters/SignedDecimalToBigDecimalLastByteTest.java

您可以在下面看到响应字帖的示例:

           09 exchangerate               PIC S9(6)V9(7).
           09 accountBalance             PIC S9(13)V9(2).

示例大型机响应:

20200931        1234567C  ADAM1 NO ZOO TESTACCOUNT O, SAMPLE SITE1L
 0212013000105101YYY SAMPLECO                                            Currentacc                       EUR000000000000000000000332589A00000000000000ä00000002005410ä00000000332589A00000000000000ä00000000000000ä91193000105037XXX SAMPLECO                                            Checkingac                       EUR000000000000000000002786655I00000000000000ä00000000000000ä00000000000000ä00000000000000ä00000000000000ä

【问题讨论】:

我不确定,但您似乎正在尝试将 COBOL 签名的显示字段转换为 Java BigDecimal。它是否正确?数据的转储显示会很有帮助。如果我没记错的话,S9(13)V99 显示字段长 15 个字节,隐含十进制前 13 个字节。第一个字节或最后一个字节都可以携带符号 overpunch,尽管默认是最后一个字节。前四位是符号,后四位是数字。十六进制 C 是正值,十六进制 D 是负值,十六进制 F 是无符号(假定为正)值。 那是真的 :),我用我正在解码的字帖字段更新了第一篇文章 0.00 的公司余额在文件转储中应如下所示:X'F0F0F0F0F0F0F0F0F0F0F0F0F0F0C0'。 -200541.00 公司余额应如下所示:X'F0F0F0F0F0F0F0F2F0F0F5F4F1F0D0' 作为一名 Java 开发人员,我无法修改大型机响应 :( 我用示例响应和字帖结构更新了第一篇文章。 我不是要你修改主机文件。我要求您提供大型机文件的十六进制文件转储,否则我无法帮助您找出问题所在。 【参考方案1】:

很遗憾,我的声誉不足以发表评论!

我不确定问题中是否有足够的细节来回答这个问题。 它怀疑你收到的字符流需要转换。

我建议参考ASCII and EBCDIC Translation Tables,看看你有没有灵感。

【讨论】:

以上是关于如何将 Cobol 响应中的签名显示字段解码为 Java 中的 BigDecimal的主要内容,如果未能解决你的问题,请参考以下文章

在 Mainframe COBOL 中,如何向控制台操作员发送消息,等待响应,然后继续?

django rest框架使用jwt RS256解码签名错误

如何将 Python 变量转换为等效的 cobol 组变量?

如何接受部分变量(字符串)作为cobol中的动态值?

使用 circe 在 Scala 中 JSON 将嵌套字段解码为 Map[String, String]

如何在新签名字段中关联先前的签名