in reply to Converting Mainframe EBCDIC data

What are the byte-values in the COMP strings? Most likely they got corrupted during transfer. It seems that Convert::IBM390 provides a hexdump function to see the byte values.

The hex output for the BCD numbers should be (or quite close to):

00 06 79 24 3F

Personally, I prefer the manual approach of using substr to get at the bytes and then Encode::decode to convert strings from CP1047 if needed. I also unpack the BCD numbers manually.

If the module works for you in other cases, most likely the data went bad.

Replies are listed 'Best First'.
Re^2: Converting Mainframe EBCDIC data
by Anonymous Monk on Sep 27, 2013 at 11:06 UTC
    Thanks for your reply. This is the first time I am using this Convert::IBM390 module. I tried using Convert::EBCDIC but it too had issues with converting COMP fields. Any pointers on how to manually unpack the COMP fields using Encode::decode or Code Page 1047. Thanks again. Really appreciate it.

      See substr for getting at the bytes, and then Encode for documentation about the decode function. For decoding COMP fields, I use the following:

      sub decode_COMP3 { my $digits = unpack "H*", $_[0]; #warn "COMP-3: $digits\n" if $digits =~ m!^0?404040!; if( $digits =~ m!^(?:40)+(?:00|f0)*$!i ) { warn "Invalid (space) content for field detected: $digits."; $digits=~ s![4f]0!00!g; } elsif( $digits =~ /[abcdef]\d/ ) { my $old= $digits; $digits=~ s![a-f]!0!g; warn "Invalid number/misaligned content for field detected [$o +ld] -> [$digits]."; }; my $sign = chop $digits; if ($sign eq 'D' or $sign eq 'd') { $sign = '-' } elsif ($sign eq 'C' or $sign eq 'c') { $sign = '+' } elsif ($sign eq 'F' or $sign eq 'f') { $sign = ' ' } elsif ($sign =~ /^\d+$/) { $digits .= $sign; $sign = '' } else { $digits .= $sign; $sign = '?' }; "$sign$digits" };

      If you have numbers with an implicit decimal point, you need to add that in afterwards.