0

I have a function that should receive data in hex EBCDIC format and convert it to ASCII.

For example, transforming the data, F1F1F0F0 should give me a 1100 in ASCII, or 31313030 in hex ASCII.

What I've found is this:

    def __decode_ASC_EBCDIC_DT(self, data):
    if (data[0] == '3'):
        #HEX ASCII
        dt_ = ''.join(chr(int(data[i:i + 2], 16)) for i in range(0, len(data), 2))
        return dt_
    elif (data[0] == 'F'):
        #HEX EBCDIC
        try:
            tmp  = bytearray(ord(c) for c in data)
            dt_ = ''.join(tmp.decode('cp500'))
        except:
            print('can\'t convert:' + data)
        return dt_

but it seems that CP500 is transfroming my data in 'ãããã' and in this case this is incorrect. (tmp is correct bytearray(b'F1F1F0F0'))

Any ideas, or should I make my own dictionary for EBCDIC?

Bogdan
  • 349
  • 1
  • 4
  • 15

2 Answers2

1

bytearray(b'F1F1F0F0') is not what you seem to think it is. It's the byte representation of the ASCII string 'F1F1F0F0'.

>>input = bytearray(b'F1F1F0F0')
>>> for item in input:  print(item)
70
49
70
49
70
48
70
48

What you're passing in is, from a EBCDIC point of view, meaningless: EBCDIC 48, 49, and 70 are undefined, so codecs.decode is going to give meaningless output.

I'm not sure where you're getting the input from, but if you want to convert an EBCDIC string to ascii, you can do this:

>>> input=bytearray([241, 241, 240, 240])
>>> for item in input: print(item)
241
241
240
240
>>> import codecs
>>> codecs.decode(input, 'cp500')
'1100'
Kevin McKenzie
  • 627
  • 3
  • 18
  • From wiki, looking at the table (for example EBCDIC Code Page 00037) https://en.wikipedia.org/wiki/EBCDIC_037 the string that I get is the representation of Row F + column 1 = F1 => 1 – Bogdan Nov 21 '16 at 08:31
  • You are right regarding the bytearray, that was my bad, but is there a different way of using cidecs.decode on a hex of EBCDIC, or how to convert HEX ebcdic to bytearray ? – Bogdan Nov 21 '16 at 08:40
  • I'm not sure what you're asking. The bytearray that I put in as an example is a HEX EBCDIC byte array, of x'F1F1F0F0', I just put them in as decimal numbers for ease of example. And codecs.decode is turning them into the equivalent ASCII string. – Kevin McKenzie Nov 21 '16 at 17:35
  • It was my mistake as I was treating the input as non HEX (data) after changing the call to bytearray.fromhex(data).decode('cp500') all works like a charm :) thanks! – Bogdan Nov 22 '16 at 10:03
0

The error in the above code was that the input should be treated as HEX (Thanks to Kevin for pointing it out).

The corrected code:

    def __decode_ASC_EBCDIC_DT(self, data):
if (data[0] == '3'):
    #HEX ASCII
    dt_ = ''.join(chr(int(data[i:i + 2], 16)) for i in range(0, len(data), 2))
    return dt_
elif (data[0] == 'F'):
    #HEX EBCDIC
    try:
        dt_ = ''.join(bytearray.fromhex(data).decode('cp500'))
    except:
        print('can\'t convert:' + data)
    return dt_
Bogdan
  • 349
  • 1
  • 4
  • 15