在python中将ebcdic解码为ascii /可读文本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在python中将ebcdic解码为ascii /可读文本相关的知识,希望对你有一定的参考价值。

我有一个以'cp500'编码的IBM大型机文件(我被告知),它将被解码为ascii或可读文本。该文件来自使用IPSwitch工具传输到Windows的unix服务器。

我已经尝试过以下代码,无法实现我的目标:

sample data = 'ðñðòðõÅäù@@@@@@@ððð :BÄÑðò÷øò@@@JaÈK' - in txt file

import codecs

with open(file, "rb") as ebcdic:
    ascii_txt = codecs.decode(ebcdic, "cp500")
    print(ascii_txt)

这产生了类型错误

"TypeError: decoding with 'cp500' codec failed (TypeError: a bytes-
like object is required, not '_io.BufferedReader')"

然后我尝试了这两个,

with open(file, 'r', encoding='cp500') as f:
    for line in f:
        print(line)

with codecs.open(file, 'r', encoding='cp500')
    for line in f:
        print(line)

我也尝试过国际编码“cp1140”格式 -

with open(file, 'r', encoding="cp1140") as f:
    for line in f:
       print(line)

我期待一个可读的输出 - 字帖布局 - 像这样...

0001***********
0002...........
0003...........

但以上三种打印输出为:

C¢C£C¢C¥C¢C§CeCuC¾       C¢C¢C¢âCdCjC¢C¥C¼C½C¥   [/Ch.

我也尝试在“rb”模式下读取文件:

with open(file, 'rb') as f:
    for line in f:
        print(line)

这是产量低于产量 -

b'xc3xb0xc3xb1xc3xb0xc3xb2xc3xb0xc3xb5xc3x85xc3xa4xc3xb9@@@@@@@xc3xb0xc3xb0xc3xb0 :Bxc3x84xc3x91xc3xb0xc3xb2xc3xb7xc3xb8xc3xb2@@@Jaxc3x88K'

这是我第一次处理ebcdic / mainframe文件 - 任何有关解码的帮助都将受到赞赏!

提前致谢 :)

答案

我怀疑EBCDIC数据是用Latin-1解码的,并且在你正在使用的TXT文件中用UTF-8保存。

让我们尝试用你的例子的缩写版本重建:

>>> copybook = '0102 [/H.'

这是最初制作的。该文本使用EBCDIC进行编码:

>>> '0102 [/H.'.encode('cp500')
b'xf0xf1xf0xf2@Jaxc8K'

这就是在原始大型机文件中写入的字节序列。您也可以在通用(非Python)表示中将其写为:

F0 F1 F0 F2 40 4A 61 C8 4B

现在这些字节用Latin-1或CP-1252(“Windows Latin-1”)解码。如果您在Windows机器上执行此操作,可能会发生这种情况:

>>> with open(file) as f:
...     text = f.read()
>>> text
'ðñðò@JaÈK'

您可以像这样模拟这种错误编码:

>>> '0102 [/H.'.encode('cp500').decode('latin1')
'ðñðò@JaÈK'

这是你在帖子开头显示的字符串。它已经比仅仅处理大型机文件的问题更糟糕 - 它是大型机文件的一个mojibake!

现在,为了使事情变得更糟,这个字符串使用UTF-8保存到文件中。我们也试一试:

>>> '0102 [/H.'.encode('cp500').decode('latin1').encode('utf8')
b'xc3xb0xc3xb1xc3xb0xc3xb2@Jaxc3x88K'

根据最后一个片段(使用'rb'模式打开并打印输出),这些是TXT文件中包含的字节。

现在这些字节不再是EBCDIC了。使用Latin-1和UTF-8的编码往返扭曲了内容:

>>> '0102 [/H.'.encode('cp500').decode('latin1').encode('utf8').decode('cp500')
'C¢C£C¢C¥ [/Ch.'

这是你在问题中首次尝试时得到的输出。

为了从这种情况中恢复,你需要撤消失真:

>>> distorted = '0102 [/H.'.encode('cp500').decode('latin1').encode('utf8')
>>> distorted
b'xc3xb0xc3xb1xc3xb0xc3xb2@Jaxc3x88K'
>>> recovered = distorted.decode('utf8').encode('latin1').decode('cp500')
>>> recovered
'0102 [/H.'

...或者从文件中读取时,您可以让open为您执行第一个解码步骤:

>>> with open(file, encoding='utf8') as f:
...     data = f.read()
...     text = data.encode('latin1').decode('cp500')

对于完整的示例行,这将产生以下文本:

'010205EU9       000x80x9aâDJ02782   [/H.'

我不是100%肯定这是原文。它包含一些控制字符(809A)和非ASCII字母(“â”)。也许000...782块必须被解释为二进制blob。但我希望这种分析可以帮助您进一步解决这个问题!

以上是关于在python中将ebcdic解码为ascii /可读文本的主要内容,如果未能解决你的问题,请参考以下文章

EBCDIC 到 ASCII 转换

EBCDIC 到 ASCII 无法正常工作

将 VB EBCDIC 文件转换为 ASCII,其中字帖记录以 01 分隔

通过 USS 中的 xlc fgets() 控制从 ASCII 到 EBCDIC 的自动转换

python 在Python中将ASCII转换为String

Python3:试图将 b' ' 字符串解码为 ascii