2016-09-29 14 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;