왜 당신의 입력 길이 제한이 잘못됐는가

발행: (2026년 3월 16일 PM 01:35 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

문제 이해하기

아마도 데이터베이스 필드, 텍스트 입력, 혹은 maxlength 속성을 가진 <input>을 사용하고 있을 것입니다. 전 세계 사용자를 대상으로 할 때, 코드가 길이를 계산하는 방식이 잘못되었을 가능성이 높습니다.

우리는 그라페임 클러스터(grapheme cluster) 라는 개념에 초점을 맞춰 텍스트 길이에 대한 실용적이고 구조적인 접근 방식을 살펴볼 것입니다. 이 가이드를 끝까지 읽으면 표준 문자열 길이 속성이 왜 실패하는지, 그리고 국제 사용자를 배려하도록 이를 어떻게 고쳐야 하는지 이해하게 될 것입니다.

사용자에게 이름을 입력받고 “20자” 로 제한한다면 실제로 무엇을 의미할까요?

  • JavaScript에서 문자열의 length 속성은 UTF‑16 코드 유닛을 측정합니다.
  • Java나 C# 같은 언어에서도 종종 코드 유닛을 측정합니다.
  • MySQL 같은 데이터베이스에서는 바이트 또는 유니코드 코드 포인트를 측정할 수 있습니다.

이들 중 어느 것도 사용자가 “문자”라고 생각하는 것을 나타내지 못합니다.

그라페임 클러스터

유니코드 용어로, 사용자가 시각적으로 하나의 단위로 인식하는 텍스트를 그라페임 클러스터 라고 합니다. 그라페임 클러스터는 기본 문자에 뒤따르는 하나 이상의 결합 문자로 구성됩니다.

예시

  • 문자 é는 단일 코드 포인트(U+00E9)로 표현될 수도 있고, 기본 문자 e(U+0065) 뒤에 결합 급성 악센트 ◌́(U+0301)가 붙은 형태로 표현될 수도 있습니다. 시각적으로는 1개의 그라페임 클러스터이지만, 단순히 string.length 로 확인하면 2가 됩니다.
  • 힌디어에 사용되는 데바나가리 문자 क्ष्म 은 여러 코드 포인트로 이루어져 있지만 1개의 그라페임 클러스터에 해당합니다.
  • “여성 농부” 이모지 👩‍🌾 은 “여성” 이모지(U+1F469), 제로 폭 연결자(Zero Width Joiner, U+200D), 그리고 “쌀 이삭” 이모지(U+1F33E) 로 구성됩니다. 이는 3개의 코드 포인트(그리고 훨씬 더 많은 바이트!)이지만, 사용자 입장에서는 1개의 문자로 인식됩니다.

유니코드가 내부적으로 어떻게 동작하는지 더 알고 싶다면 W3C 문자 인코딩 핵심 개념을 참고하세요.

입력 제한이 문제를 일으키는 이유

입력 길이 제한을 엄격히 적용하면 그라페임 클러스터 중간에서 텍스트가 잘릴 위험이 있습니다.

데이터베이스에 하드 제한이 있다고 가정해 보세요. 사용자가 10자로 보이는 문자열을 붙여넣었지만 실제로는 12개의 코드 포인트를 차지합니다. 백엔드가 임의의 바이트 또는 코드 포인트 경계에서 문자열을 자르면, 결합 악센트가 기본 문자와 분리되거나, 가족 이모지가 떠다니는 머리만 남는 식으로 깨질 수 있습니다.

이로 인해 발생하는 문제:

  • 손상된 데이터베이스 레코드
  • 깨진 사용자 인터페이스
  • 아랍어, 인도계, 동남아시아 스크립트 사용자는 물론 국기 이모지를 사용하는 사용자에게 접근성 문제가 발생

실용적인 해결책

견고하고 신뢰할 수 있는 국제화 시스템을 구축하려면 길이를 그라페임 클러스터 단위로 측정해야 합니다. 최신 프로그래밍 환경에서는 표준을 준수하는 내장 도구를 제공합니다.

웹 개발에서는 ECMAScript 국제화 API의 Intl.Segmenter 를 이용하는 것이 가장 효율적인 방법입니다.

// 이모지, 결합 다이아크리틱, 표준 라틴 문자를 포함한 문자열.
const userInput = "👩‍🌾éx";

// 코드 유닛(UTF‑16)
console.log(userInput.length); // 7

// 올바른 방법: Intl.Segmenter 사용
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
const segments = segmenter.segment(userInput);

// 실제 그라페임 클러스터 수 세기
let graphemeCount = 0;
for (const _ of segments) {
  graphemeCount++;
}

console.log(graphemeCount); // 3

Intl.Segmenter 를 표준으로 삼으면 그라페임 클러스터 수를 정확히 셀 수 있습니다.

우리는 사용자의 로케일에 관계없이 신뢰할 수 있는 시스템을 만들 책임이 있습니다. 웹 애플리케이션에서 글로벌 모범 사례를 구현하는 방법에 대해 더 깊이 알고 싶다면 W3C 국제화 기법 문서를 참고하세요.

0 조회
Back to Blog

관련 글

더 보기 »