블로그 글이 너무 짧지 않은지 확인하려고, 글자수를 세는 작은 스크립트를 하나 만들었습니다. 별거 아니죠. 글을 넣으면 몇 글자인지 세어주기만 하면 되니까요.
그런데 결과가 이상했습니다. 눈으로 보면 2천 자쯤 되는 글인데, 스크립트는 6천 자라고 했어요. 딱 3배. 처음엔 “내가 글을 이렇게 많이 썼나?” 싶었는데, 다른 글도 전부 3배로 나오는 걸 보고 알았습니다. 글이 문제가 아니라 세는 방식이 문제였던 겁니다.
범인: 글자를 센 게 아니라 바이트를 셌다
제가 쓴 명령은 유닉스의 wc라는 도구였습니다. 글자수를 세라고 wc -m을 줬죠.
wc: 유닉스 계열에서 글자·단어·줄 수를 세어주는 기본 도구.
-m은 “글자(character) 수를 세라”는 뜻입니다.
-m이 분명 “글자를 세라”인데 왜 3배가 나왔을까. 여기서 인코딩이라는 걸 알아야 합니다.
인코딩(encoding): 사람이 읽는 글자를 컴퓨터가 저장하는 숫자(바이트)로 바꾸는 규칙. 대표가 UTF-8입니다.
컴퓨터는 글자를 그대로 저장하지 못하고, 바이트라는 숫자 덩어리로 바꿔서 저장합니다. 그런데 영어와 한글은 이 덩어리 크기가 다릅니다.
- 영어
a→ 1바이트 - 한글
가→ 3바이트 (UTF-8 기준)
바이트(byte): 컴퓨터가 데이터를 세는 기본 단위. 글자 하나가 몇 바이트인지는 인코딩과 언어에 따라 다릅니다.
즉 가나다는 사람 눈엔 3글자지만, 컴퓨터 저장 공간으로는 9바이트입니다. 제 스크립트가 준 “3배”의 정체가 바로 이거였어요. 글자가 아니라 바이트를 세고 있었던 겁니다. 한글은 1글자가 3바이트니까 딱 3배로 부풀려진 거죠.
그럼 -m은 왜 바이트를 셌나
여기가 진짜 함정입니다. wc -m은 원래 글자를 셉니다. 단, 조건이 있어요. “이 시스템이 지금 어떤 언어·인코딩을 쓰는지”를 알려주는 설정(로케일)이 있어야 글자로 셉니다. 그 설정이 비어 있으면, wc는 “몰라, 그냥 바이트로 셀게” 하고 물러납니다.
로케일(locale): 시스템이 쓰는 언어·지역·인코딩 설정. 이게 있어야 프로그램이 한글을 “3바이트짜리 글자”로 제대로 인식합니다.
제 환경은 그 설정이 비어 있었어요. 그래서 -m을 줬는데도 글자가 아니라 바이트를 세어버린 겁니다. 명령은 맞게 줬는데, 환경이 그 명령의 전제를 안 갖추고 있었던 거죠.
확인: 3글자가 9로 나오나
원인을 추측만 하고 넘어가면 안 됩니다. 직접 확인해봤어요. 가나다 세 글자를 넣어봤습니다.
printf '가나다' | wc -m
# 결과: 9
3이 나와야 하는데 9가 나왔습니다. 딱 3배. 이걸로 “바이트를 세고 있다”가 확실해졌습니다. 세 글자 × 3바이트 = 9바이트니까요.
해결: ‘글자’를 확실히 세는 도구로 바꾼다
로케일 설정을 고칠 수도 있지만, 그건 환경마다 다르고 또 비어 있으면 같은 문제가 재발합니다. 그래서 아예 글자를 확실하게 세는 방법으로 바꿨습니다. 저는 윈도우라 PowerShell을 쓰는데, 여기선 문자열의 .Length가 항상 글자 수를 돌려줍니다(바이트가 아니라).
('가나다').Length # 결과: 3
같은 가나다인데 이건 정확히 3입니다. 바이트가 아니라 글자를 세는 도구를 쓰니 문제가 사라졌어요.
뼈아팠던 진짜 교훈
측정이 틀렸다는 것보다 더 아팠던 게 있습니다. 사실 저는 그 전에 글이 좀 짧은 것 같다는 이야기를 들었는데, 그때 이 스크립트를 근거로 “측정해보니 충분한데요?” 하고 반박했거든요. 그런데 그 측정이 3배로 부풀려진 가짜 숫자였습니다. 실제 글은 정말로 짧았고, 눈으로 본 판단이 맞았던 겁니다.
숫자는 객관적으로 보이니까 사람의 감보다 믿음직해 보이죠. 그런데 측정 도구 자체가 틀리면, 그 숫자는 감보다 못합니다. 시험 채점기가 고장 났으면, 눈으로 검산한 사람이 옳은 것과 같아요. 그 뒤로는 숫자가 사람의 체감과 어긋날 때, 사람보다 먼저 측정 도구를 의심하게 됐습니다.
그래서 뭘 하면 되나
한글(또는 이모지·중국어 등)을 다루는데 글자수·길이가 이상하게 나온다면, 이 순서로 의심하세요.
| 증상 | 의심 | 확인·해결 |
|---|---|---|
| 한글 글자수가 딱 3배 | 🔴 바이트를 세고 있음(인코딩) | printf '가나다' | wc -m이 9면 확정 |
wc -m인데 글자로 안 셈 | 🔴 로케일(언어 설정) 비어 있음 | 로케일 지정, 또는 아래로 대체 |
| 확실히 글자를 세고 싶다 | 🟢 언어의 문자열 길이 함수 | PowerShell .Length, 파이썬 len() 등 |
한 문장 요약: 한글 글자수가 3배로 나오면 ‘글자’가 아니라 ‘바이트’를 센 것이고, 세는 도구가 틀렸다면 그 숫자는 눈으로 본 판단보다 못하다.
바이트와 글자를 구분하는 건 컴퓨터가 글을 어떻게 저장하는지 아는 첫걸음입니다. 평소엔 신경 쓸 일이 없다가, 글자수를 세거나 문자열을 자를 때 딱 한 번 발등을 찍죠. 저처럼 3배짜리 숫자에 속지 않으시길 바랍니다. 그리고 무엇보다 — 숫자가 이상하면 세는 도구부터 의심하세요. 도구를 믿고 사람의 눈을 무시했다가, 저는 멀쩡한 판단을 틀렸다고 우길 뻔했습니다.