首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中解码ASCII文件中的COMP-3压缩字段?

在Python中解码ASCII文件中的COMP-3压缩字段?
EN

Stack Overflow用户
提问于 2015-03-24 20:28:25
回答 3查看 4.6K关注 0票数 3

我有一个以前是EBCDIC编码的文件,它是使用dd转换成ASCII码的。但是,有些行包含我想要阅读的COMP-3压缩字段。

例如,我要解码的其中一行的字符串表示为:

代码语言:javascript
复制
'15\x00\x00\x00\x04@\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x0c777093020141204NNNNNNNNYNNNN\n'

我要读取的字段由PIC S9(09) COMP-3 POS. 3指定,即从第三个字节开始的字段,解码时为9字节长(因此,根据COMP-3 spec,编码时为5字节长)。

我理解COMP-3规范,我也知道对于这一行,这个字段的整数值应该是315,但是我不知道该怎么做才能真正解码这个字段。我也不确定这个文件是不是用dd转换成ASCII码是个问题。

以前有没有人研究过类似的问题,或者我是不是明显漏掉了什么?谢谢!

EN

回答 3

Stack Overflow用户

发布于 2015-04-04 21:48:01

是的,文件包含非字符数据,并且在文件级或记录级从EBCDIC转换为ASCII,这是一个问题。这不是什么工具被用来做这件事的问题。

到目前为止,对您来说最简单的事情是请求仅以字符形式向您提供数据。如果数据包含带符号的字段,则符号应该是单独的,如果有隐含的小数位,则应该是实际的,或者由缩放值指示(以对您更方便的为准)。

然后,您不需要转换任何内容。我永远不能理解人们怎么会认为他们可以给你包含“随便”的EBCDIC数据,并期望你把它整理出来。

如果您点击EBCDIC标签,您将发现一些其他解决方案,如果由于某些愚蠢的原因,无法从EBCDIC源获得字符数据,则可以应用这些解决方案。既然他们已经给了你一些废话,他们可能会想出一些愚蠢的理由。如果是这样,(礼貌地)向你的老板记录下来。

如果你得到字符数据,那么你可以使用dd或其他方法来转换它(如果你仍然得到看起来滑稽的东西,请查看代码页)。

如果您转换非字符数据,事情会被酸洗的原因如下所示:

代码语言:javascript
复制
05  a-packed-decimal-positive-five COMP-3 PIC S9 VALUE +5.
05  a-character-asterisk PIC X VALUE "*".

在EBCDIC中,这两个值都有十六进制值5C。两者都将转换为ASCII星号。COMP-3的值5就丢失了。请注意,COMP-3可以在低位符号之外,为其每个字节接受任意一对数字。当你碰巧碰上一个控制字符时,请使用Pickle。对于“二进制”字段也是如此,确实更糟糕,因为意外命中的可能性更大。

票数 1
EN

Stack Overflow用户

发布于 2015-05-20 09:25:35

如果要执行反向字符编码转换,则可以确定值;因为有充分的理由怀疑这一点,所以最好的做法是像Bill Woodger建议的那样,以文本格式获取数据的新副本,或者获取原始数据的新副本,但不要使用数据固有的二进制部分的字符转换来损坏数据。在此特定情况下,我确信该值是可确定的;但作为0d377 (+377)而不是0d315 (+315)。

希望可以理解以下几点:

ASCII字符串(给定\xEncoded):

代码语言:javascript
复制
'15\x00\x00\x00\x04@\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x0c777093020141204NNNNNNNNYNNNN\n'

ASCII (十六进制):

代码语言:javascript
复制
  ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+
X'31350000000440000000000C000000000C3737373039333032303134313230344E4E4E4E4E4E4E4E594E4E4E4E0A'
           -04-    ASCII x04->x37 in EBCDIC [control character End of Transmission (EOT)]
             -40-  ASCII x40->x7C in EBCDIC [or xB5 or x80 or xEC or ?? per @ is a variant character in EBCDIC]

EBCDIC:

代码语言:javascript
复制
  ....+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+
x'F1F5000000377C000000000C000000000CF7F7F7F0F9F3F0F2F0F1F4F1F2F0F4D5D5D5D5D5D5D5D5E8D5D5D5D525'
           -37-    EBCDIC x37->x04 in ASCII [control character End of Transmission (EOT)]
             -7C-  EBCDIC x7C->x40 in ASCII [or A7 or 25 or ?? per x7C does not represent an invariant character in EBCDIC]

PIC S9(09) COMP-3 POS. 3中的数据字节,即压缩二进制编码十进制(BCD),对于所示刻度线中位置5到14的5个字节;10个十六进制数字000000377C,表示正十进制整数值377。我毫不怀疑,这是原始值。

偶然的是,对于该特定字符串,从EBCDIC到ASCII的转换由于无法往返于字符转换而未损坏。记录中接下来的两个值也可能定义相同,并且在与EBCDIC之间的转换中也不受数据丢失的影响;即,码位为x0C的控制字符在EBCDIC和ASCII码中是相同的,并且都具有正零的十进制值。

虽然可能还有其他可能的代码页来尝试往返,但CP00037为x7C提供了一个具有有效符号半字节和有效转换的强大竞争者;315的值似乎非常不可能,因为保留的EBCDIC控制字符x31必须转换为ASCII码x04而不是x91或xBA,并且最有可能的EBCDIC x5C莫名其妙地必须转换为ASCII码x40而不是x2A或作为负值x5D莫名其妙地转换为ASCII码x40而不是x29;没有考虑任何非首选的标志可能性,这两者都没有任何意义。

票数 0
EN

Stack Overflow用户

发布于 2019-08-23 03:40:12

经过大量的试验和错误,我注意到的是,直接编码到Ascii格式将导致除了最后一个数字和符号之外的正确数字。有一个转换表来对最后一个数字进行转换。下面是我对一些适用于我的用例的快速而肮脏的代码所做的工作。我的文件被加载到pandas中的数据框中,我调用此函数通过传入值和小数位数来为我进行转换。

代码语言:javascript
复制
sign = {'{': 1,'A': 1,'B': 1,'C': 1,'D': 1,'E': 1,'F': 1,'G': 1,'H': 1,'I': 1,'}': -1,'J': -1,'K': -1,
'L': -1,'M': -1,'N': -1,'O': -1,'P': -1,'Q': -1,'R': -1 }

last_digit = {'{': 0,'A': 1,'B': 2,'C': 3,'D': 4,'E': 5,'F': 6,'G': 7,'H': 8,'I': 9,'}': 0,'J': 1,'K': 2,
'L': 3,'M': 4,'N': 5,'O': 6,'P': 7,'Q': 8,'R': 9 }

def unpack(value,decimal):

    l = value.str[-1:]
    s = l.map(sign)
    d = l.map(last_digit)
    num = value.str[:-1]
    return (num.apply(int)*10+d)*s/10**decimal

现在,数据帧中的新字段可以是:

代码语言:javascript
复制
df['unpacked'] = unpack(df['Packed'],2)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29232656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档