2016-09-29 81 views
1

我有一个来自IBM大型机源的需要解析并转换为ASCII的EBCDIC编码的数据文件。我可以通过以十六进制读取每个字节的数据进行转换,并在ASCII上查找相应的匹配项。从IBM数据文件解压字段

我的问题是EBCDIC编码的文件有30个字节被打包,需要解压才能得到实际值。我正在尝试使用PHP pack/unpack函数以及Perl的方式,但没有找到运气。我得到的价值似乎并不是我正在寻找的确切价值。我尝试用C c H h N解包它。

假设该文件包含EBCDIC编码数据; 包字段上的位置635-664,30个字节长 DATA1 = 9个字节 DATA2 = 9个字节 DATA3 = 3个字节 DATA4 = 3个字节 DATA5 = 3个字节 DATA6 = 3个字节

PHP:

 
    $datafile = fopen("/var/www/data/datafile", "rb");
    $regebcdicdata = fread($datafile, 634); 
    $packfields = fread($datafile, 30); 
    $arr= unpack('c9data1/c9bdata2/c3data3/C3data4/C3data5/C3data6',$packfields); 
    print_r($arr); 
PERL:
 
    open my $fh, '<:raw', '/var/www/html/PERL/test'; 
    my $bytes_read = read $fh, my $bytes, 634; 
    my $bytes_read2 = read $fh, my $bytes2, 30; 
    my ($data1,$data2,$data3,$data4,$data5,$data6) = unpack 'C9 C9 C3 C3 C3 C3',  $bytes2; 

UPDATE: 已经找到了解决办法。这30个字节以指定格式打包。所以我只是使用PHP解压缩函数解压缩。

用于EBCDIC转换。我读取它的每个字节,使用bin2hex()函数获取十六进制值,找到匹配的ASCII十六进制值并获取ASCII表示,以便用户可以使用chr()函数以可读格式查看它。

我使用了转换表https://www.ibm.com/support/knowledgecenter/SSZJPZ_11.3.0/com.ibm.swg.im.iis.ds.parjob.adref.doc/topics/r_deeadvrf_ASCII_and_EBCDIC_Conversion_Tables.html

+0

您需要包括数据的东西,否则没有人会能够尝试您。你还应该包括你已经尝试过的实际代码。 [编辑]这个问题,并请添加。 – simbabque

+0

由于机密性,我不能包含数据。不过,我可以给你我在Perl和PHP中使用的代码。 – user3472277

回答

3

我不可能帮助你解开那三十个字节而不知道它们是如何被打包的。当然,你一定有一些想法?

至于常规EBCDIC文本,你需要建立正是您的文档使用的代码页,然后你可以简单地使用Perl IO进行解码

假设你正在处理code page 37,那么你就可以打开你的像这样的文件

open my $fh, '<:encoding(cp37)', 'ebcdic_file' or die $! 

然后你可以正常读取数据。它将被检索为Unicode字符

+0

太棒了!谢谢。所以我需要检查他们这些数据是如何被打包的。我用我使用的代码编辑了我的帖子。我是否正确地做这件事? – user3472277

+0

@ user3472277鲍罗廷说的是,如果你知道数据是什么,就不需要'解包',因为它们不是真正的包装,它们只是有奇怪的编码。找出它是什么编码,Perl可以自动为你读取它。 – simbabque

+0

@simbabque:从OP的代码看来,它有634字节的EBCDIC编码字符,接着是30字节的其他字符。无论这件事是否真的包装好,我都说不清楚。 – Borodin

0

这是疯狂的猜测,因为我不知道你正在使用哪个EBCDIC代码页,也不知道如何将三十个字节打包。但是有一个渺茫的机会,它会做你想要

请尝试运行此程序,并把结果告诉我们

use strict; 
use warnings 'all'; 
use feature 'say'; 

my @data = do { 
    open my $fh, '<:encoding(cp37)', '/var/www/html/PERL/test' or die $!; 
    local $/; 
    my $data = <$fh>; 
    unpack '@634 A9 A9 A3 A3 A3 A3', $data; 
}; 

say for @data;