Thanks to Uri, Dan and Bob.
I thought I was the only one who could spell 'mainframe' here. I am 
pleasantly surprised.
Ok, I figured out that the best way to get a mainframe file containing 
packed decimals is to FTP it as binary and do the conversion in  Perl.
I know the record structure so I know where to expect the packed decimals 
(pd).
I find that all the bytes are reversed. Something to do with some "Endian" 
? (No, not me!)

Adjacent bytes need to be swapped. For e.g 'START ' is  0xe3e2 d9c1 00e3 
(0xe2 is 'S' and so on)

There are no CR or LF characters...

Think I am going somewhere with this. 

Now I have a pd in a variable called $digits. This is still in EBCDIC.

I need to separate out the last 4 bits (used for signing the field)  and 
convert it to ascii (e.g 0xC should  be 'C', 0xE should be 'F') so I know 
what the sign was. Many of you know that  the last 4 bits are used for 
sign in a pd field and 'D' is -ve and others +ive

Convert all but the sign using hex() and sign it properly.

When I tried to rotate out the last 4 bits into a variable, I found the >> 
did not give me the expected value.  Nor does XOR, when I tried to read 
the sign (the last 4 bits).

Thanks for any help.





Bob Rogers <[EMAIL PROTECTED]>

Sent by: [EMAIL PROTECTED]
08/17/2003 06:37 AM

 
        To:     Ranga Nathan <[EMAIL PROTECTED]>, Dan Sugalski <[EMAIL PROTECTED]>
        cc:     [EMAIL PROTECTED]
        Subject:        Re: [Boston.pm] Separating out hexadecimals


[Apologies for the broken return address in the previous message.]

   From: Ranga Nathan <[EMAIL PROTECTED]>
   Date: Fri, 15 Aug 2003 19:30:05 -0700

   Guess I posed the question wrong. I needed to convert IBM's packed 
   decimals to an ascii string of numbers. Say in 4 byes I have a value 
   0x1234567C

   I need to see this value as '1234567' , the last 0xC being a sign 
   indicator. I foud out that hex() can do this.

But hex is for parsing; you want to print it as "hex" so it can be
reinterpreted as decimal.  How about something like this:

                 $result = substr(sprintf('%x', substr($data, $start, 
$len)), 0, -1)+0;

   1.  substr (or unpack) to extract the field;

   2.  sprintf '%x' to convert from PD to decimal digit string;

   3.  substr($field, 0, -1) to drop the sign; and finally

   4.  add zero to cause perl to drop leading zeros.

Sound worth a try?

   This is a mess! I need to think through this. Firstly I need to know 
how 
   the mainframe converts these packed decimals into ascii.

I'm pretty sure I have my copy of "Principles of Operation" lying around
somewhere . . . but it's a good thing that we don't need it; hell might
freeze over before I find it.  Fortunately, the worse that could happen
is that the mainframe stores the digits in a different order than you
expect, which only requires some experimentation with
split/reverse/join.

   From: Dan Sugalski <[EMAIL PROTECTED]>
   Date: Sat, 16 Aug 2003 12:55:31 -0400

   At 7:30 PM -0700 8/15/03, Ranga Nathan wrote:
   >However even before this is a problem. When I get the file from the
   >mainframe, it has already been converted to ASCII but these hex values
   >will be translated to some unintelligble characters.

   If it's already gone through an ASCII->EBCDIC converter and the data 
   was in binary form, you're out of luck--the data has been corrupted. 
   The only way to be able to do this is to make sure that the fields in 
   question (if not the whole file) doesn't get converted.

As long as the conversion is reversible (i.e. doesn't map two EBCDIC
codes to the same ASCII code), you can recover the original, if you know
the mapping.

  -- Bob
_______________________________________________
Boston-pm mailing list
[EMAIL PROTECTED]
http://mail.pm.org/mailman/listinfo/boston-pm



_______________________________________________
Boston-pm mailing list
[EMAIL PROTECTED]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to