
왜 화면에선 멀쩡하고 전송만 하면 깨질까?
외부 파트너사와 레거시 시스템을 연동할 때, TCP/IP 소켓이나 파일 형태로 고정 길이(Fixed-Length) 전문을 주고받는 일은 여전히 흔합니다. 금융권, 공공기관, 제조 ERP 등 오래된 시스템들은 인코딩 표준으로 EUC-KR을 고집하는 경우가 많죠.
테스트 환경에서는 완벽했던 전문 전송이 실제 운영에서 간헐적으로 바이트(Byte) 자릿수가 어긋나며 전체 데이터가 뒤틀리는 치명적인 오류를 낸 경험, 혹시 있으신가요? 저는 있습니다. 그것도 여러 번.
⚠️ 고정 길이 전문에서 바이트 오차란?
고정 길이 전문은 각 필드의 바이트 수가 약속된 규격에 정확히 맞아야 합니다. 단 1~2 바이트가 밀리면 그 뒤에 이어지는 수백 바이트 데이터가 모두 한 칸씩 엇나가 완전히 다른 값으로 해석됩니다.
범인 식별: CP949 확장 완성형 한글
현대 웹 환경, 최신 DB, VS Code 같은 모던 에디터는 UTF-8과 CP949를 완벽하게 지원합니다. 그래서 화면에서는 모든 한글이 정상으로 보입니다. 문제는 바로 이 '잘 보임'이 함정입니다.
사용자들이 오타나 특수 조합 한글을 입력할 때 문제가 발생합니다.
실제 오류 유발 사례
| 사용자 입력 (정상처럼 보임) | EUC-KR 변환 후 | 문제 |
|---|---|---|
| 폐쇄 → 퍠쇄 | ?쇄 (문자 소실) | 2바이트 손실 |
| 3개월 → 3개뤙 | 3개? (문자 소실) | 2바이트 손실 |
| 뷁 (단독) | ? (완전 소실) | 2바이트 손실 |
🔍 EUC-KR vs CP949 차이 핵심 요약
표준 EUC-KR은 KS X 1001 기반으로 2,350자만 지원합니다. 반면 CP949(확장 완성형)는 Microsoft가 이를 확장해 11,172자의 현대 한글을 모두 수용합니다. '퍠', '뤙', '뷁' 같은 글자는 CP949에는 있지만 EUC-KR에는 없습니다.
수작업 디버깅의 한계와 자동화의 필요성
오류가 나면 그제서야 전문 파일을 Notepad++로 열어 인코딩을 깨진 상태로 확인해야 합니다. ?쇄성 이런 식으로 깨진 글자가 그제야 모습을 드러내죠.
하지만 수천, 수만 건의 데이터 속에서 눈을 부릅뜨고 깨진 글자를 찾아내는 건 그야말로 엄청난 노가다입니다. 이 경험이 저를 자동화로 이끌었습니다.
💡 자동화가 필요한 이유
- 전송 전 단계에서 문제 문자를 사전 차단할 수 있다
- Notepad++ 수작업 확인 없이 즉시 하이라이팅 가능
- 백오피스 검증 로직에 태워두면 파트너사와의 분쟁을 원천 차단
- 운영 데이터 생성 단계에서 품질을 보증할 수 있다
EUC-KR 비표준 문자 자동 색출 PHP 함수
아래 함수는 문자열을 받아 EUC-KR 범위 밖의 한글을 빨간색 하이라이팅으로 표시해 줍니다. 데이터 전송 전 검증 단계나 백오피스 화면에 바로 붙여 사용할 수 있습니다.
<?php
// 테스트용 문자열 (실제로는 파일 내용이나 DB 데이터)
$str = "무릎 연개골, 슬개골, 퍠쇄증, 어깨탈골, 123, ab, 뷁";
$str = nl2br($str);
/**
* EUC-KR 비표준 한글(CP949 확장 문자) 자동 색출기
* @param string $str CP949 인코딩 문자열
* @return string 비표준 한글을 하이라이팅한 HTML 문자열
*/
function chkEUCKRstr($str) {
$result = '';
// 1. CP949 → UTF-8 변환 (퍠, 뷁 등 확장 문자 유실 없이 읽기 위해 'CP949' 지정)
$utf8_str = @iconv('CP949', 'UTF-8', $str);
if (!$utf8_str) return $str; // 변환 실패 시 원본 반환
// 2. UTF-8 상태에서 한 글자씩 분리 (멀티바이트 안전 처리)
preg_match_all('/./su', $utf8_str, $matches);
foreach ($matches[0] as $char) {
// 3. 한글(가~힣, 자음/모음)인지 유니코드 범위로 판별
if (preg_match('/[\x{3130}-\x{318F}\x{AC00}-\x{D7AF}]/u', $char)) {
// 4. 핵심: EUC-KR 변환 시도 → 실패 시 false (비표준 문자 확정)
$isStrictEucKr = @iconv('UTF-8', 'EUC-KR', $char);
$display_char = @iconv('UTF-8', 'CP949', $char);
if ($isStrictEucKr === false) {
// 비표준 문자 → 빨간색 하이라이트
$result .= '<span style="color:red; font-weight:bold; background:yellow;">'
. $display_char
. '</span>';
} else {
// 표준 EUC-KR 한글 → 그대로 출력
$result .= $display_char;
}
} else {
// 5. 한글 외 문자 (공백, 쉼표, 영문, 숫자 등) → 검사 생략
$result .= @iconv('UTF-8', 'CP949', $char);
}
}
return $result;
}
// 결과 출력
echo chkEUCKRstr($str);
?>
코드 작동 원리 단계별 분석
이 함수의 핵심 아이디어는 iconv의 변환 실패 특성을 역이용하는 것입니다. 단계별로 살펴보겠습니다.
CP949 → UTF-8 변환
iconv('CP949', 'UTF-8', $str)로 입력 문자열을 UTF-8로 변환합니다. EUC-KR이 아닌 CP949를 소스 인코딩으로 지정하는 이유는, 확장 완성형 문자('퍠', '뷁')를 유실 없이 읽어오기 위함입니다.
멀티바이트 안전 글자 분리
preg_match_all('/./su', ...)로 UTF-8 문자열을 한 글자씩 안전하게 분리합니다. s(dotall), u(유니코드) 플래그로 멀티바이트 문자를 정확히 처리합니다.
유니코드 범위로 한글 판별
\x{3130}-\x{318F}(자음·모음), \x{AC00}-\x{D7AF}(완성형 한글) 범위로 해당 글자가 한글인지 먼저 걸러냅니다. 영문·숫자·특수문자는 검사를 건너뜁니다.
🎯 핵심: EUC-KR 변환 시도 → 실패 캐치
iconv('UTF-8', 'EUC-KR', $char)로 EUC-KR 변환을 시도합니다. 변환에 성공하면 표준 EUC-KR 문자, false를 반환하면 EUC-KR 범위 밖의 비표준 문자임이 확정됩니다. 이 역이용 트릭이 함수의 전체 핵심입니다.
실전 적용 팁 & 마무리
이 검증 함수를 백오피스 데이터 조회 화면이나 전문 생성 직전 단계에 삽입해두면, 문제 데이터를 전송 전에 화면으로 즉시 확인할 수 있습니다.
✅ 실전 적용 체크리스트
- 입력 폼 저장 시 DB에 넣기 전
chkEUCKRstr()호출 후 비표준 문자 경고 - 전문 생성 배치 실행 전 해당 함수로 사전 스캔 후 오류 레코드 격리
- 파트너사 전송 실패 시 로그에 해당 함수 결과를 함께 기록하여 원인 즉시 특정
- PHP 8.x 환경:
iconv대신mb_convert_encoding병행 사용도 고려
이 작은 함수 하나를 검증 로직에 태워두는 것만으로도, 파트너사와 "전문이 깨진다, 안 깨진다" 신경전을 벌일 일도, Notepad++를 열어 수만 행을 육안으로 뒤지는 일도 사라집니다.
B2B 데이터 연동에서 알 수 없는 바이트 밀림 현상으로 고통받고 계신 개발자분이라면, 데이터 생성 단계에서 반드시 한 번 이 문자열 스캐닝을 돌려보시길 강력히 권합니다.
💬
비슷한 인코딩 지옥, 겪어보셨나요?
EUC-KR 말고도 UTF-8 ↔ EUC-KR 혼재 환경, CP949 파일 파싱 등 다양한 인코딩 이슈 경험을 댓글로 공유해 주세요.
개발자끼리 서로의 삽질을 나누면 모두가 삽질을 덜 수 있습니다. 😄
이 글이 도움이 되셨다면 공감 하나가 큰 힘이 됩니다! 🙏
'Code > PHP' 카테고리의 다른 글
| PHP ftp_put 고정장 전문 오프셋 깨짐 해결 — 범인은 FTP_ASCII 모드였다 (0) | 2026.04.22 |
|---|---|
| 반복문 속 쿼리가 서버를 죽인다 — PHP N+1 문제와 SQL 실행 최소화 실전 가이드 (0) | 2026.04.21 |
| PHP Imagick 멀티 TIFF 자동 변환이 서버를 다운시킨 이유와 해결법 (1) | 2026.04.15 |
| PHP 개발자의 에디터 변천사: 드림위버부터 AI CLI 환경까지 (0) | 2026.03.25 |
| Hello World, Again: 해킹을 딛고 다시 쓰는 2026년 PHP 개발기 (0) | 2026.03.24 |