본문으로 건너뛰기
ZEKILO Dev
텍스트

글자 수와 바이트 수 — UTF-8·EUC-KR·Shift_JIS

2026.10.03 업데이트 · 4분 읽기

같은 글도 UTF-8, UTF-16, EUC-KR(CP949), Shift_JIS(CP932)에서 바이트 수가 다릅니다. 한글·일본어·이모지의 바이트 수와 DB VARCHAR, 고정 길이 전문에서 길이를 맞추는 법을 정리했습니다.

글자 수·바이트 수 세기 바로 사용하기

글자 수와 바이트 수는 다른 단위입니다. 안녕하세요 ZEKILO는 12글자지만 UTF-8로는 22바이트, EUC-KR로는 17바이트입니다. DB 컬럼 길이나 고정 길이 전문처럼 바이트로 길이를 재는 곳에서는 상대 시스템이 쓰는 문자 인코딩으로 세어야 합니다. 글자 수·바이트 수 세기에 글을 넣으면 글자 수, UTF-16 길이, UTF-8·EUC-KR·Shift_JIS 바이트 수를 한 번에 볼 수 있습니다.

글자 하나는 몇 바이트인가

아래 표의 숫자는 모두 바이트 수입니다.

글자 UTF-8 UTF-16 EUC-KR(CP949) Shift_JIS(CP932)
A 영문·숫자 1 2 1 1
가 한글 3 2 2 표현 불가
あ 히라가나 3 2 2 2
漢 한자 3 2 2 2
ア 반각 가타카나 3 2 표현 불가 1
😀 이모지 4 4 표현 불가 표현 불가
  • UTF-8은 코드 포인트 범위에 따라 1~4바이트를 씁니다(RFC 3629). U+007F까지 1바이트, U+07FF까지 2바이트, U+FFFF까지 3바이트, 그 위는 4바이트입니다. 한글, 가나, 자주 쓰는 한자는 3바이트입니다.
  • UTF-16은 2바이트 단위입니다. U+FFFF를 넘는 글자는 단위 2개(4바이트)를 씁니다. JavaScript의 length와 Java의 String.length()는 바이트가 아니라 이 단위의 개수입니다.
  • EUC-KR은 ASCII를 1바이트, 한글·가나·한자를 2바이트로 적습니다. Shift_JIS는 ASCII와 반각 가타카나를 1바이트, 가나·한자를 2바이트로 적고 한글은 적지 못합니다.

EUC-KR은 CP949(MS949), Shift_JIS는 CP932(Windows-31J) 기준입니다. 시스템마다 다를 수 있습니다. WHATWG Encoding 표준의 euc-kr은 KS X 1001과 통합 완성형을 합친 것, 곧 Windows 코드 페이지 949를 가리킵니다.

예시로 보는 차이

입력 글자 수 UTF-16 길이 UTF-8 EUC-KR(CP949) Shift_JIS(CP932)
안녕하세요 ZEKILO 12 12 22 17 한글 5자 표현 불가
こんにちは ZEKILO 12 12 22 17 17
👍🏻가 2 5 11 — —
똠방각하 4 4 12 8 —
①髙 2 2 6 — 4

「—」는 그 인코딩으로 표현할 수 없는 글자가 들어 있다는 뜻입니다.

  • 👍🏻가의 엄지 이모지는 코드 포인트 2개(이모지와 피부색)로 이루어져 있지만 화면에는 한 글자로 보입니다. 사람이 보는 글자 단위(자소 클러스터, UAX #29)로는 2글자, 코드 포인트로는 3개, UTF-16 길이는 5입니다. 글자 수를 무엇으로 세느냐에 따라 답이 달라집니다.
  • 똠은 KS X 1001의 한글 2,350자에 없는 글자입니다. CP949는 확장 영역에 이 글자를 두어 2바이트로 적지만, KS X 1001 범위만 지원하는 시스템에서는 깨질 수 있습니다.
  • ①과 髙는 JIS X 0208에 없고 CP932 확장에 있는 글자입니다.

DB VARCHAR: n은 글자인가 바이트인가

VARCHAR(10)의 10이 무엇을 세는지는 제품마다 다릅니다(2026년 10월 기준 각 제품 문서).

제품 n의 단위
MySQL VARCHAR(n) 글자 수
PostgreSQL varchar(n) 글자 수
Oracle VARCHAR2(n) BYTE·CHAR로 지정. 생략하면 NLS_LENGTH_SEMANTICS(기본값 BYTE) 적용
SQL Server varchar(n) 바이트 수

바이트 기준 컬럼에서는 문자 인코딩이 곧 한도입니다. 홍길동은 EUC-KR로 6바이트, UTF-8로 9바이트입니다. 바이트 기준 10짜리 컬럼에 한글은 EUC-KR이면 5자, UTF-8이면 3자까지 들어갑니다. EUC-KR 데이터베이스를 UTF-8로 옮길 때 한글이 2바이트에서 3바이트로 늘어 길이 초과 오류가 나는 이유입니다. 옮기기 전에 가장 긴 값의 바이트 수를 새 인코딩으로 세어 보세요.

글자 수 기준인 MySQL에도 행 전체 65,535바이트 한도가 있어서, 실제로 선언할 수 있는 최대 길이는 문자 집합에 따라 달라집니다.

고정 길이 전문에서 주의할 점

고정 길이 전문은 필드마다 바이트 수가 정해져 있고, 남는 자리를 공백이나 0으로 채웁니다. 한 필드가 1바이트만 어긋나도 뒤의 필드가 모두 밀립니다.

  • 채우는 수는 바이트로 계산합니다. 10바이트 이름 필드에 홍길동을 넣으면 EUC-KR에서는 6바이트이므로 공백 4개를 붙입니다. 글자 수(3)로 계산해 공백 7개를 붙이면 13바이트가 됩니다.
  • 자를 때는 글자 경계에서 자릅니다. 2바이트 글자의 첫 바이트만 남으면 그 글자와 뒤따르는 내용이 깨집니다. 글자 단위로 더해 가다가 한도를 넘기 직전에 멈춥니다.
  • 줄바꿈은 CRLF면 2바이트, LF면 1바이트입니다.
  • 상대 시스템이 표현하지 못하는 글자는 미리 걸러 냅니다. 이모지, CP949에 없는 한자가 그런 예입니다. 글자 수·바이트 수 세기는 EUC-KR이나 Shift_JIS로 표현할 수 없는 글자가 몇 개인지 경고로 알려 줍니다.

정리

  • 길이 제한을 보면 단위가 글자인지 바이트인지, 바이트라면 어떤 문자 인코딩인지 먼저 확인합니다.
  • 한글은 UTF-8에서 3바이트, EUC-KR에서 2바이트입니다. 😀 같은 이모지는 UTF-8에서 4바이트이고 EUC-KR·Shift_JIS로는 적을 수 없습니다.
  • length가 돌려주는 값은 UTF-16 길이여서 글자 수와도, 바이트 수와도 다를 수 있습니다.
  • 보내기 전에 글자 수·바이트 수 세기로 실제 바이트 수를 확인하세요. 입력값은 브라우저 안에서만 처리됩니다.

이 글과 관련된 도구

출처와 기준

다른 가이드