amandeep gandhi
amandeep gandhi

Reputation: 21

EBCDIC Encoding cp037 Python

I am doing EBCDIC (CP037) encoding in python and sending the file to mainframe

input_bytes = bytearray.fromhex(pad_str)
# Decode the bytes using EBCDIC encoding
ebcdic_str = input_bytes.decode('cp037')

it's working fine , but for certain values it's generating incorrect values.

writing the hex on values from mainframe as ebcdic are non-printable characters

for : 43, it converts to BC and for 56 to DA. if the the value is 340312 i get correct value. if it's 343012 , i get 3BC012 which is incorrect. these are the hex values.

please find the sample function.first function is coverting to comp-3

def unsigned_comp3(decimal_num, bytecount):
sign_nibble = "1111"  # F for positive numbers
# Convert the decimal number to a string of BCD digits
bcd_str = ''.join([f"{int(d):04b}" for d in str(decimal_num)])
bcd_len = len(bcd_str)
# Add a leading nibble of "1111" to indicate that the number is 
packed in COMP-3 format
bcd_str = bcd_str + sign_nibble
print(f'bcd{decimal_num}: {bcd_str}')
# Group the BCD digits into pairs of bytes
byte_pairs = [bcd_str[i:i + 8] for i in range(0, 
len(bcd_str),8)]
print(f'bytes{decimal_num}: {byte_pairs}')
# Convert each byte pair to its hexadecimal equivalent
hex_str = ''.join([f"{int(pair, 2):02X}" for pair in 
byte_pairs])
# To EBCDIC
output_str = to_ebcdic(hex_str, len(str(decimal_num)), 
bytecount)
# Return hex string
return output_str

this function converts to ebcdic

def to_ebcdic(input_str, input_length, bytecount):
# Store the last character
sign_char = input_str[-1]
# Concatenate the remaining character and the sign character
if sign_char == "D":
    # Remove the first character
    stripped_str = input_str[1:]
    input_hex = stripped_str[:input_length - 1] + sign_char
elif sign_char == "F":
    input_hex = input_str[:input_length] + sign_char
else:
    # Remove the first character
    stripped_str = input_str[1:]
    input_hex = stripped_str[:input_length] + sign_char
# Padding if input_str is less than bytecount
pad_str = pad_string(input_hex, bytecount)
print(f'{pad_str}')
# Convert the hex string to bytes
input_bytes = bytearray.fromhex(pad_str)
print(f'input bytes{input_str}: {input_bytes}')
# Decode the bytes using EBCDIC encoding
ebcdic_str = input_bytes.decode('cp037')
print(f'ebcdic string{input_str}: {ebcdic_str}')
# Return the decoded string
return ebcdic_str

sample value in mainframe(incorrect) input : 343012F

enter image description here

Upvotes: 0

Views: 198

Answers (0)

Related Questions