C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

c# 에서 ascii 형 byte 배열을 문자열로 변환해야 하는 경우가 있습니다.
무슨 내용인고 하니 만약 소켓작업을 한다 치면 문자열을 넘겨 준다고 가정합니다.
넘겨주는 쪽에서는 ascii 형 문자열을 1byte 배열에 문자를 담아 넘겨줄것입니다.
그러나 C# 에서 문자처리는 Char 로 처리하며 한문자가 2바이트입니다.
당연히 받은 1byte 문자열을 2byte char 형태의 배열인 string 으로 변환해야겠죠..
ASCII.GetString, 형변환 , Convert.Tochar 등의 키워드로 알아보겠습니다.

먼저 문자열이 아닌 한문자를 변환시도 하겠습니다.

1. ASCII 형 Byte 에서 Char 로 하나의문자 변환

1. Type Casting

C#에서 정수를 문자로 변경하는 가장 간단한 방법은 형변환입니다. 정수를 문자 유형으로 쉽게 캐스팅 할 수 있는데, 그 이유는 문자의 핵심이 단순히 숫자 (ASCII 값)이기 때문입니다. 이 접근 방식은 간단하고 효과적이기 때문에 개발자들에게 인기가 있습니다.

static void Main(string[] args)
{
    byte byteValue = 65; // 'A' 의 아스키값
    char charValue = (char)byteValue;

    Console.WriteLine("C# Type Casting 을 이용한 문자 변환");
    Console.WriteLine("Byte Output      : " + byteValue);
    Console.WriteLine("Character Output : " + charValue);
}
C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

2. Convert.ToChar()

C#의 Convert.ToChar() 메서드는 직접 형식 캐스팅 메서드에 비해 정수를 해당 문자 표현으로 변환하는 더 쉽고 읽기 쉬운 방법을 제공합니다.
이 방법은 코드에서 변환을 보다 명확하고 이해하기 쉽게 만들려는 경우에 유용합니다. Convert.ToChar()를 사용하면 복잡하지 않고 정수를 해당 문자로 빠르고 쉽게 변환할 수 있습니다.

static void Main(string[] args)
{
    byte byteValue = 65; // 'A' 의 아스키값
    char charValue = Convert.ToChar(byteValue);

    Console.WriteLine("C# Convert.ToChar 를 이용한 문자 변환");
    Console.WriteLine("Byte Output      : " + byteValue);
    Console.WriteLine("Character Output : " + charValue);
}
C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

2. 아스키 byte 문자열을 String 으로 변환

이제 byte 문자열을 String 으로 변환하여 보도록 하겠습니다.
대표적인 사용법은 아래와 같습니다.

Method 1: Encoding.ASCII.GetString()의 사용 예제

System.Text.Encoding.ASCII.GetString
파생된 간단한 함수로 System.Text.ASCIIEncoding.GetString
를 사용하시면 됩니다. 사용법은 두개 모두 똑같습니다.

static void Main(string[] args)
{
    var input = new byte[] { 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65 }; // "Example";
    ASCIIEncoding ascii = new ASCIIEncoding();
    String decoded = ascii.GetString(input);
    Console.WriteLine("Decoded string: '{0}'", decoded);
}
C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

그런데 말입니다. 여기에 한가지 문제점이 있습니다. 만약 소켓으로 받은 문자열이 뒤에 0 으로 패딩되어 있다면 약간의 오류가 나옵니다.
예를 들어보면 위의 예제에서 input 변수가 다음처럼 뒤에 0x00 으로 몇개가 채워져서 입력되었다면
var input = new byte[] { 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00 }; // “Example”;
C 개발자라면 문자열 뒤에 0이 붙었으니 문자열로 취급 안하고 당연히 위의 예제와 결과가 같을꺼라 상상합니다.
이쉽게도
Console.WriteLine(“Decoded string: {0} {1}”, decoded, decoded.Length);
출력부분에서

C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

이렇게 출력이 됩니다. 우리가 원한건 출력 문자열은
Decoded string: Example 7
일텐데 말이죠

그래서 이걸 해결하기 위해 입력 값에서 모든 0을 지워줘야 합니다.
또는 처음부터 순차검색을 시도 하여 0이 나오면 앞부분만 변환하는 방식도 있습니다.

Method 2. Linq 를 사용하여 모든 0 제거

static void Main(string[] args)
{
    var input = new byte[] { 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x00 }; // "Example";
    input = input.Where(x => x != 0x00).ToArray(); // 모든 0 제거 
    string decoded = System.Text.Encoding.ASCII.GetString(input).Trim();
    Console.WriteLine("Decoded string: {0} {1}", decoded, decoded.Length);
}
C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

어떤가요 원하는 결과가 나왔죠?

Method 3. StringBuilder 사용하여 필요부분만 취하기

정말 만약 다음과 같이 마지막 값에 0 이 있고 그 이후에 쓰레기 값이 있다면
var input = new byte[] { 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x00, 0xCD, 0xCD, 0xCD }; // “Example”;
개발자는 윗부분과 같은 결과 값을 바라지만 결과값은 다릅니다.
이를 해결하기 위해 0을 찾고 앞부분을 끊는 작업을 저수준으로 처리해보겠습니다.
위의 ASCIIEncoding 은 사용하지 않고 한문자 한문자 변환하여 StringBuilder 에 넣는 방식으로 처리합니다.

static void Main(string[] args)
{
    var input = new byte[] { 0x45, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x00, 0xCD, 0xCD, 0xCD, }; // "Example";
    StringBuilder cropinput = new StringBuilder();
    foreach (var ch in input)
    {
        if (ch == 0) break;
        cropinput.Append((char)ch);
    }

    Console.WriteLine("Decoded string: {0} {1}", cropinput.ToString(), cropinput.Length);
}
C#에서 ASCII 형 Byte 배열을 문자열로 변환하는 방법

어떤가요 완전히 원하는 결과물이죠?

결론

C#에서 ascii 형 byte 배열을 문자열로 변환하는 작업은 자주 발생하는 작업이며 다양한 방법이 있습니다. 각 방법에는 고유한 이점이 있으며 선택 항목은 코드를 명확하고 읽기 쉽게 만드는 데 필요한 항목에 따라 달라집니다.
System.Text.Encoding.ASCII.GetString 은 최고의 문자열 변환도구입니다.
한문자 변환시 캐스팅은 짧고 간단합니다.Convert.ToChar()는 변환을 명시적으로 만드는데 요용한 방법입니다.
배열 중간에 섞여 있는 특수값(0x00) 을 삭제하는 방법도 보았습니다. Where(x => x != 0x00)
이제 편하신 방법, 상황에 맞는 방법을 고려하여 변환 하시면 됩니다.

Leave a Comment