Saturday, December 29, 2007

C#: Convert EBCDIC to ASCII

public string ConvertEBCDICtoASCII(string strEBCDICString)
{
int[] e2a = new int[256]{
0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15,
16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31,
128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7,
144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26,
32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33,
38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94,
45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63,
186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34,
195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201,
202,106,107,108,109,110,111,112,113,114,203,204,205,206,207,208,
209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215,
216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,
123, 65, 66, 67, 68, 69, 70, 71, 72, 73,232,233,234,235,236,237,
125, 74, 75, 76, 77, 78, 79, 80, 81, 82,238,239,240,241,242,243,
92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255
};

char chrItem = Convert.ToChar("0");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < strEBCDICString.Length; i++)
{
try
{
chrItem = Convert.ToChar(strEBCDICString.Substring(i, 1));
sb.Append(Convert.ToChar(e2a[(int)chrItem]));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return string.Empty;
}

}
string result = sb.ToString();
sb = null;
return result;
}

9 comments:

  1. Thanks for posting this code. This is exactly what I need!!

    ReplyDelete
  2. can u tell me how to convert ASCII to EBCDIC format?

    ReplyDelete
  3. Sure. Here's the link: http://kseesharp.blogspot.com/2007/12/convert-ascii-to-ebcdic.html

    ReplyDelete
  4. Thanks for posting this code! Do you know how to read packed data in an ebcdic file?

    ReplyDelete
  5. I am not sure if it is possible to read packed data outside of a mainframe environment like that. You would notice that this method works on assuming a 1 to 1 byte conversion, which is NOT how packed data is stored internally. Sorry I could not help, but if you do figure it out please post here for others. Thanks!

    ReplyDelete
  6. It should probably be noted that you're talking about converting a specific encoding in EBCDIC and ASCII. The byte translations will depend on what EBCDIC and ASCII character code set ID's you need. I realize the post is old, but as I just found it today I'm sure others have found it as well.

    ReplyDelete
  7. Hi Koushik,I am not understood the use of array declared initially, and what the values it contain , int[] e2a = new int[256] , will you pls explain this, as i need to write similar kind of code to convert EBCDIC to ASCII, As well pls let me know do u have any idea abt how to convert COMP-3 to ASCII

    ReplyDelete
  8. How about just doing this? (Decoding codepage 37 ebcdic from ascii converted to byte array:
    Private EBCDICDecoder As System.Text.Decoder = System.Text.Encoding.GetEncoding(37).GetDecoder
    Private Function ConvertEbcdicToAscii(ByVal ebsidic_bytes As Byte()) As String
    Dim length As Integer = ebsidic_bytes.Count
    Dim chars() As Char = New Char(length - 1) {}
    EBCDICDecoder.GetChars(ebsidic_bytes, 0, length, chars, 0)
    Return New String(chars)
    End Function

    ReplyDelete
  9. To the Guy wanting to know how to convert Packed Decimal fields (VB.NET). You will need to convert everything that is not packed decimal from ebcdic to ascii, and convert the packed decimal fields with the following function:

    Private Function ConvertSignedPackedDecToLong(ByVal orig_bytes As Byte()) As Long
    '//SEE PACKED DECIMAL DOCUMENTATION HERE: http://support.microsoft.com/kb/65323
    '//this will convert a signed packed decimal binary format to a base 10 value

    Dim length As Integer = orig_bytes.Length
    'highest power of 10 - lose one since 10 ^0 is first, lose another for 4 bits used for sign
    Dim highest_power_of_ten As Integer = length * 2 - 2
    Dim base_ten_value As Long = 0

    Dim cur_byte As Byte
    Dim high_nibble_byte As Byte
    Dim low_nibble_byte As Byte
    Dim high_nibble_value As Long
    Dim low_nibble_value As Long

    For i As Integer = 0 To length - 2
    cur_byte = orig_bytes(i)
    high_nibble_byte = CType(cur_byte >> 4, Byte) 'get the first 4 bits
    low_nibble_byte = CType((cur_byte << 4) >> 4, Byte) 'now get the right 4 bits

    'get the base 10 values from the nibbles * the power of 10
    high_nibble_value = high_nibble_byte * Math.Pow(10, highest_power_of_ten - (i * 2))
    low_nibble_value = low_nibble_byte * Math.Pow(10, highest_power_of_ten - (i * 2) - 1)
    'add the values to the total
    base_ten_value += high_nibble_value + low_nibble_value
    Next
    Dim last_byte_index As Integer = length - 1
    cur_byte = orig_bytes(last_byte_index)
    high_nibble_byte = CType(cur_byte >> 4, Byte) 'get the first 4 bits
    low_nibble_byte = CType((cur_byte << 4) >> 4, Byte) 'now get the right 4 bits

    'get the base 10 value * the power of 10
    high_nibble_value = high_nibble_byte * Math.Pow(10, highest_power_of_ten - (last_byte_index * 2))

    base_ten_value += high_nibble_value
    '--------------------------The last 4 bits determines the sign-----------------------
    Select Case low_nibble_byte
    Case PACKED_DEC_POSITIVE
    Case PACKED_DEC_UNSIGNED
    Case PACKED_DEC_NEGATIVE
    base_ten_value *= -1
    Case Else
    If length <> 2 Then
    Throw New Exception("Invalid Packed Decimal Sign Value: " & low_nibble_byte.ToString)
    End If
    End Select
    Return base_ten_value
    End Function

    ReplyDelete

Please use your common sense before making a comment, and I truly appreciate your constructive criticisms.