2010-05-18 8 views
9

EBCDIC 형식의 값이 "000000 {"입니다. 나는 a.Net Int32 타입으로 변환하고 싶다. 아무도 내가 그것에 대해 뭘 할 수 있는지 알려 줄 수 있습니까 ?? 그래서 내 질문에 EBCDIC에 부호가있는 숫자가 들어있는 문자열이 주어진다. .NET Int32로 변환하려면 어떻게해야 할까?C# .net에서 EBCDIC를 ASCII로 변환하는 방법

미리 감사드립니다.

+1

꽤 나쁜 제목; 이 질문은 ASCII와 완전히 관련이 없습니다. – Nyerguds

답변

1

일반적으로 정확한 System.Text.Encoding 클래스를 사용하여 EBCDIC 데이터를로드 할 수 있어야합니다 (링크는 EBCDIC 인코딩을 포함하는 모든 인코딩 목록을 가리 킵니다). 문자열은 메모리의 유니 코드이며 ASCII 인코딩을 사용하여 ASCII로 저장할 수 있습니다.

질문의 제목에서 질문하는 내용입니다. 그러나, 당신의 질문이 완전히 나에게 명확하지 않기 때문에 당신이 알고 싶었던 것인지 확신 할 수 없습니다. ASCII 문자 코드를 찾고있는 경우 ASCII 문자 만있는 한 문자를 int으로 전송할 수 있습니다. 기능 다음

+0

귀하의 제안은 문자 데이터에 대해서는 괜찮을 것이고 정확할 것입니다. 그러나 새 문자 매핑으로 번호가 변경 될 것이므로 수치 데이터에는 좋지 않습니다. – ewall

+0

@wall, 설명해 주셔서 감사합니다.EBCDIC 자체에 익숙하지 않지만 프레임 워크에 인코딩이 있다는 것을 알고있었습니다. 이것이 내가 실제로이 질문에 실제로 대답 할 지 확신하지 못한다는 것에 대한 최 하단 단락을 쓴 이유이기도합니다. 제목이 변경되지 않은 한, EBCDIC 문자 변환을 검색하고이 질문을 찾아 오는 다른 사람들에게 내 대답을 남겨 두겠습니다. 제목과 질문 텍스트가 더 명확하면 삭제 해 드리겠습니다. – Lucero

+0

사실, 이것은 문자 인코딩간에 변환하는데 훌륭한 답입니다. – ewall

0

봅니다 ..

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; 
} 
+1

아니요, 작동하지 않습니다. 질문을 더 자세히 읽으면 Sai는 바이트 배열에서 숫자 데이터 (정수)를 가져와야합니다. EBDIC에서 ASCII로 변환하면 숫자가 변경됩니다. – ewall

3

당신은 당신이 직면하고있는 것입니다으로, binary-coded decimals에 위로 읽고 싶은거야, 그리고 당신이 정말로 그것을 코딩하기 전에 응답 할 질문이있다.

값이 단일 문자이면 char 번호를 얻는 것만 큼 간단하지만 시스템이 Big Endian인지 알아야합니다 (EBDIC 인코딩 파일을 가져 오는 대부분의 메인 프레임처럼) 또는 Little Endian (더 현대적인 OS).

정수 값이 두 개 이상의 문자를 사용하고 기호 (언급 한대로)를 포함하면 더 복잡합니다. 대부분 각 문자의 각 반 (또는 "니블"또는 4 비트)은 숫자를 나타냅니다. 0부터 9까지 또는 16 진수에서 0까지의 숫자로 표시되며 문자열은 왼쪽에 0이 채워집니다. 마지막 니블에는 사인이 들어 있습니다. 이 시스템은 Zoned Decimal이라고 할 수 있습니다.

전체적으로 나는 reading this article, which should introduce you to how data is/was stored on COBOL-based mainframes으로 시작하여 올바른 방향으로 움직이는 것이 좋습니다. 이 같은 int.Parse with the correct NumberStyles options를 사용하여 (당신이 그것을 설명대로 들어오는 데이터에 가장 적합한 같은 소리)

C#에서

, 당신은 일반적인 지대로 나뉨 진수를 형성하는 변환을 수행 할 수 있습니다 :

int val = int.Parse(num, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite); 
+0

(필자는 예제 코드가 모두 자바이기 때문에 BTW, C#의 예제 코드를 계속 찾고 있습니다.) – ewall

4

다음 프로그램은 고객 중 하나로부터 데이터를 수신 할 때 EBCDIC 값을 정수로 변환하는 프로그램입니다.

using System; 
using System.Text; 

namespace ConsoleApplication6 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string strAmount = "00007570{"; 
      Console.WriteLine("{0} is {1}", strAmount, ConvertEBCDICtoInt(strAmount)); 
      strAmount = "000033}"; 
      Console.WriteLine("{0} is {1}", strAmount, ConvertEBCDICtoInt(strAmount)); 
      Console.ReadLine(); 
     } 

     // This converts "00007570{" into "75700", and "000033}" into "-330" 
     public static int? ConvertEBCDICtoInt(string i_strAmount) 
     { 
      int? nAmount = null; 

      if (string.IsNullOrEmpty(i_strAmount)) 
       return(nAmount); 

      StringBuilder strAmount = new StringBuilder(i_strAmount); 
      if (i_strAmount.IndexOfAny(new char[] { '}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R' }) >= 0) 
       strAmount.Insert(0, "-"); 

      strAmount.Replace("{", "0"); 
      strAmount.Replace("}", "0"); 
      strAmount.Replace("A", "1"); 
      strAmount.Replace("J", "1"); 
      strAmount.Replace("B", "2"); 
      strAmount.Replace("K", "2"); 
      strAmount.Replace("C", "3"); 
      strAmount.Replace("L", "3"); 
      strAmount.Replace("D", "4"); 
      strAmount.Replace("M", "4"); 
      strAmount.Replace("E", "5"); 
      strAmount.Replace("N", "5"); 
      strAmount.Replace("F", "6"); 
      strAmount.Replace("O", "6"); 
      strAmount.Replace("G", "7"); 
      strAmount.Replace("P", "7"); 
      strAmount.Replace("H", "8"); 
      strAmount.Replace("Q", "8"); 
      strAmount.Replace("I", "9"); 
      strAmount.Replace("R", "9"); 

      // Convert the amount to a int: 
      int n; 
      if (int.TryParse(strAmount.ToString(), out n)) 
       nAmount = n; 
      return (nAmount); 
     } 
    } 
} 
+0

이 솔루션은 실제로 EBCDIC 오버 펀치 값을 처리합니다. – lukevp

19

다음은 우리가 사용하는 확장 방법 및 단위 테스트입니다이

#region public static byte[] ConvertAsciiToEbcdic(byte[] asciiData) 
    public static byte[] ConvertAsciiToEbcdic(byte[] asciiData)  
    {   
     // Create two different encodings.   
     Encoding ascii = Encoding.ASCII; 
     Encoding ebcdic = Encoding.GetEncoding("IBM037");   

     //Retutn Ebcdic Data 
     return Encoding.Convert(ascii, ebcdic, asciiData);  
    }  
    #endregion  

    #region public static byte[] ConvertEbcdicToAscii(byte[] ebcdicData) 
    public static byte[] ConvertEbcdicToAscii(byte[] ebcdicData) 
    {   
     // Create two different encodings.  
     Encoding ascii = Encoding.ASCII; 
     Encoding ebcdic = Encoding.GetEncoding("IBM037"); 

     //Retutn Ascii Data 
     return Encoding.Convert(ebcdic, ascii, ebcdicData); 
    } 
    #endregion 
+1

질문이 EBCDIC 인코딩 된 텍스트가 아닌 EBCDIC 오버 펀치 숫자 값과 관련되어 있기 때문에 Downvoted. Simon이 제공 한 대답은이 필드에 대한 올바른 처리입니다. – lukevp

+0

그것이 나를 도왔 기 때문에 Upvoted – coloboxp

0

을 시도해보십시오이 당신을 위해 작동하는 경우 우리가 얻을 데이터는 당신이 얻을 수있는 무엇의 일부, 그래서 볼 수 있습니다 :

/// <summary> 
    /// parses a signed or unsigned decimal in EBCDIC format int an integer 
    /// </summary> 
    /// <param name="value"></param> 
    /// <returns></returns> 
    private static int? FromZonedDecimalString(this string value) 
    { 
     var trimmed = ("" + value).Trim(); 
     if (trimmed.Length == 0) 
      return null; 

     int testValue; 
     if (Int32.TryParse(trimmed, out testValue)) 
      return testValue; 

     var lastChar = Convert.ToChar(trimmed.Substring(trimmed.Length - 1, 1)); 
     var result = 0; 

     if (trimmed.Length > 1) 
      result = Int32.Parse(trimmed.Substring(0, trimmed.Length - 1)) * 10; 

     switch (lastChar) 
     { 
      case '{': 
       return result; 
      case '}': 
       return -1 * result; 
      default: 
       if (lastChar >= 'A' && lastChar <= 'I') 
        return result + lastChar - 'A' + 1; 
       if (lastChar >= 'J' && lastChar <= 'R') 
        return (result + lastChar - 'J' + 1) * -1; 
       if (lastChar >= '0' && lastChar <= '9') 
        return (result + lastChar - '0' + 1) * -1; 
       break; 
     } 
     return null; 
    } 

    /// <summary> 
    /// converts an integer value into zoned signed EBCDIC decimal format 
    /// </summary> 
    /// <param name="value"></param> 
    /// <returns></returns> 
    public static string ToZonedSignedDecimalString(this int value) 
    { 
     var str = Math.Abs(value).ToString(); 
     str = str.Substring(0, str.Length - 1); 
     var lastDigit = Math.Abs(value % 10); 

     if (value < 0) 
     { 
      if (lastDigit == 0) return str + "}"; 
      if (lastDigit == 1) return str + "J"; 
      if (lastDigit == 2) return str + "K"; 
      if (lastDigit == 3) return str + "L"; 
      if (lastDigit == 4) return str + "M"; 
      if (lastDigit == 5) return str + "N"; 
      if (lastDigit == 6) return str + "O"; 
      if (lastDigit == 7) return str + "P"; 
      if (lastDigit == 8) return str + "Q"; 
      if (lastDigit == 9) return str + "R"; 

      throw new NotSupportedException("If this throws, I'm at a loss. Last digit was: " + lastDigit); 
     } 

     if (lastDigit == 0) return str + "{"; 
     if (lastDigit == 1) return str + "A"; 
     if (lastDigit == 2) return str + "B"; 
     if (lastDigit == 3) return str + "C"; 
     if (lastDigit == 4) return str + "D"; 
     if (lastDigit == 5) return str + "E"; 
     if (lastDigit == 6) return str + "F"; 
     if (lastDigit == 7) return str + "G"; 
     if (lastDigit == 8) return str + "H"; 
     if (lastDigit == 9) return str + "I"; 

     throw new NotSupportedException("If this throws, I'm at a loss. Last digit was: " + lastDigit); 
    } 


[TestClass] 
public class IntExtensionsTests 
{ 
    [TestMethod] 
    public void TestConversion() 
    { 
     string signedDecimalString; 
     int convertedlValue; 
     for (int i = -1000001; i <= 1000001; i++) 
     { 
      signedDecimalString = i.ToZonedSignedDecimalString(); 
      convertedlValue = signedDecimalString.ConvertRightSignedJustifySignedValueToInt(); 

      Assert.AreEqual(i, convertedlValue); 
     } 
    } 
} 
관련 문제