Encoding

2024. 2. 14. 22:14개발/C#

개발을 하면서, UTF나 유니코드 등의 용어를 자주 접하지만

깊게 알아보거나 궁금한 적이 없었던 것 같다

 

오늘 업무하면서

Encoding관련 에러가 발생해서

이참에 궁금해서 알아보았다


유니코드

초창기 컴퓨터는 '영어'와 '특수문자'를 사용했다

시간이 흘러 다양한 국가의 언어를 지원하게 되면서

국제 표준이 만들어졌고, 그게 유니코드

 

UTF-7, UTF-8, UTF-16, UTF-32

인코딩 방식.

유니코드를 어떻게 컴퓨터에 저장할 것인가에 대한 내용


에러 원인

private void MQTTOnReceived(byte[] recv)
{
    string recvData = Encoding.Default.GetString(recv).Replace("\u0000", System.String.Empty);
}

 

MQTT 데이터 수신 이벤트다.

불필요한 코드는 삭제했다.

 

Encoding.Default로 데이터를 받아올때,

데이터 안에 한글이 있으면 에러가 발생한다.

 

FactoryName 값에 한글이 저장돼서

인코딩 과정에 오류가 발생했다.

 

왜 Encoding.Default는 오류가 발생하는지 이해가 안돼서

Encoding.Default가 뭔지 알아봤다.


Encoding.Default 방식

public static Encoding Default
{
    [SecuritySafeCritical]
    get
    {
        if (defaultEncoding == null)
        {
            defaultEncoding = CreateDefaultEncoding();
        }

        return defaultEncoding;
    }
}

[SecurityCritical]
private static Encoding CreateDefaultEncoding()
{
    int aCP = Win32Native.GetACP();
    return aCP switch
    {
        1252 => new SBCSCodePageEncoding(aCP),
        65001 => s_defaultUtf8EncodingNoBom,
        _ => GetEncoding(aCP),
    };
}

[SecuritySafeCritical]
[__DynamicallyInvokable]
public static Encoding GetEncoding(int codepage)
{
    Encoding encoding = EncodingProvider.GetEncodingFromProvider(codepage);
    if (encoding != null)
    {
        return encoding;
    }

    if (codepage < 0 || codepage > 65535)
    {
        throw new ArgumentOutOfRangeException("codepage", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, 65535));
    }

    if (encodings != null)
    {
        encoding = (Encoding)encodings[codepage];
    }

    if (encoding == null)
    {
        lock (InternalSyncObject)
        {
            if (encodings == null)
            {
                encodings = new Hashtable();
            }

            if ((encoding = (Encoding)encodings[codepage]) != null)
            {
                return encoding;
            }

            switch (codepage)
            {
                case 0:
                    encoding = Default;
                    break;
                case 1200:
                    encoding = Unicode;
                    break;
                case 1201:
                    encoding = BigEndianUnicode;
                    break;
                case 1252:
                    encoding = new SBCSCodePageEncoding(codepage);
                    break;
                case 65001:
                    encoding = UTF8;
                    break;
                case 1:
                case 2:
                case 3:
                case 42:
                    throw new ArgumentException(Environment.GetResourceString("Argument_CodepageNotSupported", codepage), "codepage");
                case 20127:
                    encoding = ASCII;
                    break;
                case 28591:
                    encoding = Latin1;
                    break;
                default:
                    encoding = GetEncodingCodePage(codepage);
                    if (encoding == null)
                    {
                        encoding = GetEncodingRare(codepage);
                    }

                    break;
            }

            encodings.Add(codepage, encoding);
            return encoding;
        }
    }

    return encoding;
}

 

모든 코드를 볼 수 없어서

보이는 내용만 요약해보자면

 

윈도우 운영체제의 기본 인코딩 방식을 반환하는 것 같다.

찾아보니 윈도우는 ANSI? 라는 인코딩 방식을 기본으로 사용하고,

 

이 방식은 영어를 지원, 한글은 지원하지 않는다.


UTF-8로 수정

private void MQTTOnReceived(byte[] recv)
{
    string recvData = Encoding.UTF8.GetString(recv).Replace("\u0000", System.String.Empty);
}

 

한글을 지원하는 UTF-8방식으로 수정 후,

FactoryName 한글 관련 오류가 사라졌다.

 

그 외에도, EUC-KR, CP949 등 한글지원 인코딩 방식이 있다고 한다.

개발 언어, 로직 등에만 관심을 갖다가

 

이런 기본 컴퓨터 개념을 놓치고 개발을 하고 있었다

기본기를 잘 다지자 ㅠ

'개발 > C#' 카테고리의 다른 글

C# 선그래프  (1) 2024.04.02
Modbus TCP 제어 ( 패킷 과수신 대비 )  (3) 2024.03.06
C# - class & structure  (1) 2024.02.10
소프트웨어 설계 수정  (0) 2024.01.08
모니터링 자동화 - API Parsing  (1) 2024.01.01