티스토리 뷰


C#에서 인코딩과 디코딩(Base64, UTF, Unicode 등)


이 글에서는 인코딩과 디코딩하는 방법에 대해서 알아보도록 하겠습니다. 프로그래밍을 할 때 사용자는 String 데이터 타입을 byte[] 데이터 타입으로 변경해야 하는 경우가 많습니다. 혹은 웹상에서 byte[]로 데이터를 받아서 String으로 변환을 해야 하는 경우도 많습니다.


이런 경우 개발자는 인코딩에 대한 고려를 해야 합니다. 먼저 인코딩이 무엇인가에 대해서 알아보도록 하겠습니다.


1. 인코딩이란?


문자 인코딩(文字―, 영어: character encoding) 또는 줄여서 인코딩은 문자나 기호들의 집합을 컴퓨터에서 저장하거나 통신에 사용할 목적으로 부호화하는 방법을 가리킨다. 문자 인코딩을 통해 부호화되어, 복호화하면 본래의 문자나 기호를 뜻하게 되는 부호를 문자 코드(文字―, 영어: character code)라고 한다.


문자 인코딩의 대표적인 예로 전건을 길게, 또는 짧게 두드려서 라틴 알파벳을 나타내는 모스 부호가 있으며, 라틴 알파벳, 숫자, 특수 문자 등을 정수와 그에 대응되는 7비트 이진수로 표현하는 방법인 아스키(ASCII)가 있다.


컴퓨팅 초기에는, 아스키(ASCII, 1963년), EBCDIC(1964년)과 같은 문자열 세트가 표준으로 자리잡았다. 이러한 문자열 세트의 제한은 명백했으며 수많은 애드혹(ad hoc) 방식이 개발되었다. 한중일 계열의 동아시아 스크립트를 포함하여 다중 문자(언어) 지원이 시급했다.


<출처 : 한글 위키피디아>


2. 인코딩의 종류


위의 설명을 보면, 한중일 계열의 동아시아 스크립트가 문제가 되는것을 확인할 수 있습니다. 이는 영어는 모든 문자에 대해 1byte로 변환이 가능하지만, 한글을 포함한 한중일의 언어는 2byte로 처리가 되어야 하기 때문입니다.


이러한 이유와 언어의 다양성으로 인해 문자 인코딩을 위한 방식을 여러가지가 있을 수 밖에 없습니다. 대표적인 문자 인코딩 방식은 아래와 같습니다. 


  • ASCII
  • ISO 8859:
  • CP437, CP737, CP850, CP852, CP855, CP857, CP858, CP860, CP861, CP863, CP865, CP866, CP869
  • MS 윈도 문자 집합: Windows-125X
  • 맥 오에스 로만 (Mac OS Roman)
  • 중국어 GB
  • 한국어
    • KS X 1001은 2바이트 한국어 문자 인코딩 표준이다.
    • EUC-KR
    • ISO-2022-KR
  • 유니코드 (UTF-8도 참조)
  • ANSEL 또는 ISO/IEC 6937
좀더 상세한 내역은 아래의 페이지를 참고하세요.


따라서 인코딩을 할 때 가장 주의해야 할 점은 String -> Byte할때와 Byte -> String 할때 방식이 같아야 한다는 점입니다.

즉, Unicode 방식으로 인코딩을 했는데 ASC 타입으로 디코딩을 하게 되면 예상치 못한 값이 보이게 됩니다. 서버-클라이언트나 Http를 이용한 통신 방식에서 byte 배열을 받아 처리할 때도 전송한 부분에서 사용한 인코딩 방식을 명확히 파악하고 클라이언트 부분에서도 명확히 처리를 해줘야 합니다.


3. 인코딩 관련 C# 클래스


그럼 지금부터 C#에서 인코딩을 하는 방법에 대해서 알아보도록 하겠습니다.


C#에서는 String을 Byte 배열로 변환하기 위해서 System.Text.Encoding 클래스를 지원하고 있습니다. Encoding 클래스의 상세 내역은 아래와 같습니다. Encoding 클래스의 상속 구조(Inheritance Hierarchy)를 봐도 아래에 수많은 타입의 인코딩 자식 클래스가 제공되는 것을 확인할 수 있습니다.


유니코드 방식으로 인코딩을 할려면 UnicodeEncoding 클래스를 사용하면 됩니다.  UTF8 방식으로 인코딩을 하기 위해서는 UTF8Encoding 클래스를 사용할 수 있습니다. 


좀 더 상세한 내역을 확인하고 싶으면 아래의 링크를 참조하시기 바랍니다.

.NET Framework의 문자 인코딩 : 

http://msdn.microsoft.com/ko-kr/library/ms404377.aspx



4. C#으로 인코딩 하기


코드를 통해서 String 값을 Byte 배열로 변환해 보겠습니다.  String 값을 Byte 배열로 변환하기 위해서는 GetBytes 함수를 이용할 수 있습니다. 그리고 나서 변환된 값을 String 값으로 다시 바꿔보도록 하겠습니다. 


string str = "Test Code by Gus";

string str1 = "GusEngineer Encoding Test";


byte[] byteFromStr = System.Text.Encoding.Unicode.GetBytes(str);

byte[] byteFromStr1 = System.Text.Encoding.UTF8.GetBytes(str1);


// byte 배열 

for (int i = 0; i < byteFromStr.Length; i++)

    Console.Write(byteFromStr[i] + " ");

Console.WriteLine("");


for (int i = 0; i < byteFromStr1.Length; i++)

    Console.Write(byteFromStr1[i] + " ");

Console.WriteLine("");


// Normal Encoding Result

Console.WriteLine("Normal Encoding Result  : ");

Console.WriteLine("Unicode : " + Encoding.Unicode.GetString(byteFromStr));

Console.WriteLine("UFT8 : " + Encoding.UTF8.GetString(byteFromStr1));


위의 코드를 실행하게 되면 아래와 같은 결과를 얻을 수 있습니다. Unicode와 UTF-8 방식으로 진행한 결과가 제대로 진행되었음을 보여주고 있습니다. 



그럼 반대로 UTF-8 방식으로 인코딩한 결과를 Unicode로, 그리고 그 반대로 인코딩을 해보도록 하겠습니다. 

위의 코드에서 아래의 코드를 추가합니다.


// Abnormal Encoding Result

Console.WriteLine("Abnormal Encoding Result : ");

Console.WriteLine("Unicode : " + Encoding.Unicode.GetString(byteFromStr1));

Console.WriteLine("UFT8 : " + Encoding.UTF8.GetString(byteFromStr));


위의 코드를 실행하면 아래의 결과를 얻을 수 있는데, Abnormal Encoding Result를 보시면 결과가 예상했던것과는 다른것을 확인할 수 있습니다.



5. Base64 인코딩하기


Base64 방식은 컴퓨터 분야에서 많이 쓰이는 인코딩 방식입니다. 특히 암호화와 복호화에 많이 사용되고 있습니다. BASE64에 대해서 좀더 알아보자면 다음과 같습니다.


컴퓨터 분야에서 쓰이는 Base 64 (베이스 육십사)란 8비트 이진 데이터(예를 들어 실행 파일이나, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념이다.


원래 Base 64를 글자 그대로 번역하여 보면 64진법이란 뜻이다. 특별히 64진법이 컴퓨터에서 흥미로운 것은, 64가 2의 제곱수(64 = 26)이며, 2의 제곱수들에 기반한 진법들 중에서 화면에 표시되는 ASCII 문자들을 써서 표현할 수 있는 가장 큰 진법이기 때문이다. 즉, 다음 제곱수인 128진법에는 128개의 기호가 필요한데 화면에 표시되는 ASCII 문자들은 128개가 되지 않는다.


그런 까닭에 이 인코딩은 전자 메일을 통한 이진 데이터 전송 등에 많이 쓰이고 있다. Base 64에는 어떤 문자와 기호를 쓰느냐에 따라 여러 변종이 있지만, 잘 알려진 것은 모두 처음 62개는 알파벳 A-Z, a-z와 0-9를 사용하고 있으며 마지막 두 개를 어떤 기호를 쓰느냐의 차이만 있다.


<출처 : 한글 위키피디아>


Base64 인코딩 과정


1) 아스키코드표 매핑하여 8비트에 맞게 2진수로 변환합니다.

2) 6비트 단위로 잘라서, 10진수로 변환합니다. 

3) BASE64 테이블을 매핑하고, 연산을 합니다.


Base64 방식을 인코딩 하기 위해서는 Convert.ToBase64String(byte[])과 Convert.FromBase64String(string)을 이용하여 인코딩이 가능합니다. Base64를 인코딩, 디코딩 하기 위해서는 String을 byte 배열로 바꾼뒤, 이를 다시 String으로 변환해주셔야 합니다. 


// string to string which is converted for base64

byte[] baseEncodedResult = Encoding.Default.GetBytes(test);

string baseResult = Convert.ToBase64String(baseEncodedResult);


// To decode the value

byte[] baseDecodedResuslt = Convert.FromBase64String(baseResult);

Console.WriteLine("Base 64 : " + Encoding.Default.GetString(baseDecodedResuslt));


위의 코드를 실행한 결과는 아래와 같습니다. 제대로 인코딩 결과가 나오는것을 확인할 수 있습니다.



지금 까지 인코딩에 대한 내용을 알아보았습니다. 궁금한점이 있으시면 아래에 글을 남겨주세요. 그럼 이만 줄이겠습니다.


이 글이 도움이 되셨나요?

그렇다면 아래의 그림을 클릭해주세요.



댓글