본문 바로가기
Development/C#

[내일배움캠프 77일차 TIL] 입력 값 한글, 영어, 특수문자 체크하고 바이트 다르게 계산하기

by 식냥 2024. 8. 2.
728x90


맨 처음 입력 값을 받을 때에는 단순히 텍스트 길이로 계산을 해서 문자 상관없이 무조건 입력 값 하나당 길이가 1이었다. 하지만 보통 한글은 2byte, 영어/공백/특수문자는 1byte로 계산을 하기 때문에 이를 맞춰주기 위해 로직을 다시 작성했다.

 

[ Encoding.Defalut ]

int userNameByteCnt = Encoding.Defalut.GetByteCount(inputUserName.text);
int farmNameByteCnt = Encoding.Defalut.GetByteCount(inputFarmName.text);

Defalut로 했을 때에는 한글은 3byte, 영어는 1byte로 계산이 돼서 한글을 6글자로 제한하면 영어는 18글자까지 입력 가능해서 원하는 대로 동작하지 않았다.

 

[ Encoding.Unicode ]

int userNameByteCnt = Encoding.Unicode.GetByteCount(inputUserName.text);
int farmNameByteCnt = Encoding.Unicode.GetByteCount(inputFarmName.text);

대신 Unicode를 사용하면 한글이 2byte가 된다는 정보를 보고 다음과 같이 실행했을 때는 영어도 2byte가 돼버렸다.

 

[ Custom ]

직접 카운트 추가

private void CheckNameCount()    // 글자 수 제한
{
    int userNameByteCnt = CalCulateByteCount(inputUserName.text);
    int farmNameByteCnt = CalCulateByteCount(inputFarmName.text);
    
    if (userNameByteCnt > 12 || farmNameByteCnt > 12)
    {
        maxNameLengthPopUp.SetActive(true);
        return;
    }
}

private int CalCulateByteCount(string input)
{
    // 한글: 2byte, 영어, 공백, 특수문자: 1byte
    int byteCount = 0;
    foreach (char c in input)
    {
        if (IsKorean(c))
        {
            byteCount += 2;
        }
        else
        {
            byteCount ++;
        }
    }
    return byteCount;
}

private bool IsKorean(char c)
{
    // 한글 유니코드 범위: AC00 ~ D7A3
    return c >= '\uAC00' && c <= '\uD7A3';
}

 

그래서 바로 byte 계산을 하지 않고, 입력 값 하나하나 한글인지 체크해서 직접 카운트를 올려주는 방식으로 진행했다.

원하는 방식으로 동작은 하지만, 엄연히 따지면 실제 바이트로 계산한 것이 아니라 내가 임의로 지정한 카운트만큼 올려주는 것이기 때문에 다른 방법을 더 찾아봤다.

 

문자별 다른 변환 방식

private void CheckNameCount()    // 글자 수 제한
{
    int userNameByteCnt = CalCulateByteCount(inputUserName.text);
    int farmNameByteCnt = CalCulateByteCount(inputFarmName.text);
    
    if (userNameByteCnt > 12 || farmNameByteCnt > 12)
    {
        maxNameLengthPopUp.SetActive(true);
        return;
    }
}

private int CalCulateByteCount(string input)
{
    // 한글: 2byte, 영어, 공백, 특수문자: 1byte
    int byteCount = 0;
    foreach (char c in input)
    {
        if (IsKorean(c))
        {
            byteCount += Encoding.Unicode.GetByteCount(c.ToString());
        }
        else
        {
            byteCount += Encoding.UTF8.GetByteCount(c.ToString());
        }
    }
    return byteCount;
}

private bool IsKorean(char c)
{
    // 한글 유니코드 범위: AC00 ~ D7A3
    return c >= '\uAC00' && c <= '\uD7A3';
}

UniCode는 한글을 2byte로 바꿔주고, UTF8은 영어, 공백, 숫자, 특수문자를 1byte로 바꿔주니까 한국어면 Unicode로, 아니라면 UTF8로 바꿔주면 직접 바이트 계산을 통해 크기를 체크할 수 있다.

 

근데 굳이.. 싶어서 이전처럼 직접 카운트를 올리는 방식이 더 나은 것 같다. 그리고 커스텀 방식은 1, 2 외의 다른 숫자로도 카운트를 올려서 체크 할 수 있기 때문에 더 편리하다.

 

 

728x90
반응형