UTF-8 인코딩에서의 BOM(Byte Order Mark) 문제

다양한 언어를 표현할 수 있도록 해주는 유니코드(Unicode) 인코딩에는 여러가지 방식이 있습니다. 최근 웹 환경에서 많이 쓰이는 UTF-8을 비롯해서 UTF-16, UTF-32 등이 이런 인코딩 방식을 나타내지요.

이렇게 비슷한 방식을 사용하는 문서는 Byte Order Mark(BOM)로 구별이 됩니다. 문서 맨 앞에 눈에 보이지 않는 특정 바이트(byte)를 넣은 다음 이것을 해석해서 정확히 어떤 인코딩 방식이 사용되었는지 알아내는 방법이지요.

그런데 UTF-8 인코딩 방식에서는 BOM이 문제를 일으킬 수 있습니다. BOM이 무엇이고 왜 문제를 일으키는지, 그리고 어떻게 해결해야 하는지 알아보겠습니다.

BOM의 용도와 종류

BOM은 인코딩된 문서 첫 머리에 사용되어 정확한 인코딩 방식을 알려주는 역할을 하는데 대표적인 인코딩 방식과 그에 따른 BOM 목록은 아래 표와 같습니다.

인코딩 방식 Byte Order Mark(BOM)
UTF-8 EF BB BF
UTF-16 Big Endian FE FF
UTF-16 Little Endian FF FE
UTF-32 Big Endian 00 00 FE FF
UTF-32 Little Endian FF FE 00 00

예를 들어서 문서 처음 2개의 바이트가 FE FF로 시작되면 그 문서는 UTF-16 Big Endian으로 해석되고, 반대로 FF FE로 시작되면 UTF-16 Little Endian으로 해석되는 것이지요.

그런데 UTF-8은 다른 인코딩 방식과는 다르게 BOM의 순서가 EF BB BF로 정해져 있습니다. 그래서 이 BOM은 바이트 순서와(Byte Order) 상관없기 때문에 UTF-8 Signature라고 불리지요. 즉, 해당 문서가 UTF-8로 인코딩되었다는 사실을 알리는 사인(signature)입니다.

UTF-8 BOM으로 생기는 문제

UTF-8은 인코딩 형식이 고정되어 있기 때문에 BOM이 없어도 인코딩 방식을 자동으로 알아낼 수 있습니다. 따라서 실제로는 BOM이 불필요하지요.

하지만 일부 윈도우즈 프로그램(메모장 같은)은 UTF-8 파일을 생성할 때 자동으로 BOM을 집어넣습니다. 윈도우즈 환경에서는 눈에 띄지 않는 경우가 많지만 리눅스(LINUX)나 유닉스(UNIX) 환경에서는 많은 문제를 일으키는 원인이 되지요.

대표적인 예로 PHP에서 include 구문을 사용할 때 생기는 여백(space)을 들 수 있습니다. 이것은 비단 BOM의 문제 뿐 아니라 웹 서버의 설정과도 관련이 있기 때문에 모든 경우에 생기는 문제는 아닙니다.

먼저 인터넷 익스플로러(이하 IE)에서 아래 두 링크를 열어보시기 바랍니다.

† 2010년 3월 20일: 아래 링크는 더 이상 유효하지 않습니다. ^^;

BOM이 있는 문서 인클루드, BOM이 없는 문서 인클루드

두 문서는 이미지를 인클루드하는 부분을 제외하면 같은 소스를 사용합니다. 인클루드되는 파일 역시 BOM 유무를 빼면 동일합니다.

따라서 브라우저에서 두 문서의 소스를 확인해 보면 전혀 차이가 없습니다. 하지만 IE에서 두 페이지는 다르게 보입니다.

† 파이어폭스는 문서 내에 BOM이 들어가도 제대로 처리합니다. 따라서 두 링크가 동일하게 보이지요. 또한 웹 서버 환경에 따라서도 문제 발생 여부가 달라집니다. 동일한 파일을 다른 서버에 올릴 경우에는 문제가 안생길 수도 있으니까요.

UTF-8 BOM 문제의 원인

이렇게 두 문서가 다르게 보이는 이유는 눈에 보이지 않는 BOM 때문입니다. 사실 두 문서는 완전히 동일하지 않거든요. 단지 이 차이가 일반적인 환경에서는 보이지 않을 뿐입니다. 하지만 인클루드 되는 파일을 헥사 에디터((hex editor)로 열어보면 아래 이미지처럼 차이가 드러납니다.

BOM이 있는 파일의 헥사 코드

test1.html에서 인클루드한 BOM이 있는 파일입니다.

BOM이 없는 파일의 헥사 코드

test2.html에서 인클루드한 BOM 없는 파일입니다.

† 급조해서 만들다 보니 img 태그에 alt 속성이 빠졌군요. 접근성 향상을 위해서 꼭 넣어주는 것이 좋습니다. ^^;

첫 번째 이미지 맨 앞에 보이는 세 개의 바이트, EF BB BFtest1.html에 들어가고, IE가 이 BOM을 제대로 해석하지 못하기 때문에 문제가 생기는 것이지요.

BOM 문제를 해결하는 방법

가장 좋은 방법은 BOM을 처음부터 넣지 않는 것입니다. 윈도우즈의 메모장 대신 BOM 설정이 가능한 전문적인 텍스트 에디터를 사용하는 것이 좋겠지요.

에디트플러스 BOM 설정

위 이미지는 텍스트 에디터로서 좋은 평가를 받고 있는 에디트플러스BOM 관련 옵션 설정 창입니다. UTF-8 Signature가 BOM을 가르키는데 선택 가능한 값과 그 의미는 아래와 같습니다.

  • Preserve existing signature: BOM이 있을 경우에만 그대로 유지합니다.
  • Always add signature: 항상 BOM을 넣습니다.
  • Always remove signature: BOM이 있으면 무조건 제거합니다.
  • Add signature if necessary: 필요할 경우에만 BOM을 넣습니다.

여기에서 ‘Always remove signature’로 지정하면 편집하는 모든 파일의 BOM이 제거됩니다. 다른 텍스트 에디터에도 비슷한 설정이 있는 경우가 많습니다. 예를 들어서 프리웨어 텍스트 에디터인 Notepad++는 옵션 설정 창의 ‘New Document’ 탭에서 인코딩 방식을 UTF-8 without BOM으로 설정하면 BOM이 없는 UTF-8 문서를 만들 수 있습니다.

마치며

지금껏 제 경험으로는 UTF-8 문서에서 BOM이 필요했던 경우는 없었습니다. 하지만 특정한 환경에서는 필요할 수도 있으니 상황에 따라 적절히 적용하는 것이 좋습니다.

여담이지만 처음 웹 표준을 접하고 홈페이지를 만들 때 웹 저작 툴인 마이크로 소프트익스프레션 웹 배타판을 사용했는데 CSS에서 * { margin: 0; padding: 0; }을 지정해도 여백이 생겨서 한참 헤맸었습니다. 알고보니 익스프레션 웹이 자동으로 넣은 BOM 때문이더군요.

댓글 19개가 달렸습니다. 태그: ,

  1. vervain | 2007-12-12 19:19

    아.. 이런게 있었군요. 잘 읽고 갑니다. :)

  2. 정태영 | 2008-01-13 15:35

    많은 경우 BOM 은 해가 되기 보다 도움이 됩니다. 예로 드신 php 의 include 문제는 php 에서 unicode 를... 더 정확하게는 문서의 인코딩에 대해서 제대로 지원하지 않고 있기 때문에 생기는 문제입니다.

    null terminated 방식만을 지원하는 php 에선 ucs_2 나 ucs_4, utf-16 등은 아예 사용할 수 없을 것 같네요. :)

    사실 --enable-zend-multibyte 옵션과 함께 php 를 빌드하게 되면 해결할 수 있는 문제기는 한데 php 진영은 좀 변화가 더뎌서 --;; 6.0 에서나 unicode 를 제대로 지원할거라고 하네요. 더 자세한건 아래 링크를 확인해보시기 바랍니다.

    http://bugs.php.net/bug.php?id=22108

  3. 정태영 | 2008-01-13 15:36

    혹시나 도움이 될까 해서 제가 써놨던 유니코드와 관련된 글 몇 개를 링크걸고 갑니다~!

    http://b.mytears.org/2005/01/101
    http://b.mytears.org/2005/03/136

  4. wystan | 2008-01-14 10:01

    의견 남겨주셔서 고맙습니다. :-)

    UTF-8 인코딩 문서에서의 BOM 사용은 장단점이 있는 것 같습니다.

    알려주신 링크 내용처럼 BOM을 이용해서 파일 인코딩 방식을 쉽게 알아낼 수 있는 장점이 있지만, 유닉스 계열에서는 UTF-8 BOM을 전혀 사용하지 않기 때문에 크로스 플랫폼 환경에서는 문제를 일으킬 수도 있습니다.

    그래서 개인적으로는 비단 PHP 뿐 아니라 유닉스 쉘 스크립트 등에서 문제 발생 요지가 있는 UTF-8 BOM을 가급적이면 쓰지 않는 것이 좋다는 생각을 갖고 있습니다.

    UTF-16이나 UTF-32 인코딩처럼 BOM이 문서 해석에 결정적인 역할을 한다면 필수적으로 사용해야겠지만 UTF-8은 고정된 BOM을 사용하기 때문에 실제로는 BOM이 아닌 Signature의 역할만을 하고 있으니까요.

  5. 임지원 | 2008-02-21 21:48

    리눅스에서 파일을 euc-kr ==> utf-8 으로 바꾸고 IIS 에서 돌리는데..

    FF에서는 잘 되는데.. IE에서 안되서.. 이틀을 삽질하다가 이글을 봅니다.

    정보 감사하고요.. 리눅스에서 BOM을 포함해서 파일 인코딩 변환 하는 옵션 같은게 있으면 메일 주시면 감사하겠습니다.

    그 외에 파일 변환 툴이라던지 인코딩 변환에 대한 어떤 정보라도 좋으니 있으시면 공유 부탁합니다.

  6. WoNNi' | 2008-03-07 16:33

    BOM에 관해서 DOM-Level 1 이라고만 생각했지,
    이런게 있으리라곤 생각도 못했습니다. ㅋㅋ
    지금 열심히 msdn 참고 하고 있습니다.
    생각보다 범위가 상당히 넓네요.. : )
    그리고 감수중이신 책 좀 알려주세요..
    하코사에 올렸는데.. 답변이 없으시네요~

  7. wystan | 2008-03-07 23:02

    그 날 모임에서 과음한 탓에 어제는 정신이 없어서 댓글을 못남겼어요~
    책 제목은 메일로 알려드릴게요~ 아직 공개하기가 좀 그래서요. ^^;

  8. wystan | 2008-03-07 23:04

    혹시 비슷한 정보를 찾는 분이 있을까 싶어서 임지원님께 보내드린 메일 내용을 인용합니다.

    IE에서 어떤 문제가 생기는지 모르겠지만 리눅스에서 BOM을 제거하거나 추가하는 것은 uconv를 이용해서 쉽게 처리할 수 있습니다. 물론 인코딩 변환도 가능하고요. 아래 man 페이지 참고하시기 바래요.

    http://linux.die.net/man/1/uconv

    --add-signature
    --remove-signature

    위 옵션을 사용하시면 됩니다. 데비안 Etch에서 UTF-8 파일로 테스트해봤습니다.

  9. 정서 | 2009-02-15 04:22

    좋은 글 감사합니다.
    한참 해맷는데 쉽게 해결 됬네요.

  10. 용자왕 | 2009-12-03 02:11

    w3c 적합성 검사에서 경고멘트가 계속 나와서 곤혹스러웠는데 여기에서 해결합니다.

    감사합니다 : )

  11. 이정호 | 2010-01-16 15:55

    BOM 문제로 잠깐 고생했다가 구글신에게 물어물어 찾아왔습니다.
    좋은 글 감사합니다…
    ps: 블로그에 관련문제 포스팅하기 위해 중간에 Hex 에디터 이미지 두장 퍼가도록 하겠습니다..?

  12. 김용균 | 2010-03-26 05:46

    좋은 글 감사합니다. 저만 겪는 일이 아니었군요. ㅠㅠ

  13. 세벌 | 2010-05-02 06:14

    엠에스 윈도의 노트패드 UTF-8로 XML 관련 작업하다가 멀쩡해보이는 문서가 제대로 해석이 안되는 문제로 헤매다가 흘러 흘러 왔습니다. 인코딩이란게 복잡하네요

  14. js | 2010-08-16 11:35

    이 문제 때문에 고생했는데 이런 문제였군요.
    좋은 글 감사합니다.
    정보 담아갈게요~

  15. 밤바 | 2010-12-07 18:19

    관련 내용으로 트러블슈팅하던 중 여기까지 왔군요.
    개발자들에게도 유의토록 본문 링크를 공유하였습니다.
    좋은 정보 감사합니다.

  16. 블랙 | 2011-04-07 12:44

    정보 감사합니다.
    이클립스에서 문제없다가 울트라에디트로 작업을 좀 했더니 바로 BOM 문제가 발생해 버리네요..
    울트라에디트 > 설정 > File Handling > Save 에서
    ‘Write UTF-8 BOM header to all UTF-8 files when saved’ 를 체크해제 해놓긴 했지만,,
    이미 저장된 파일들은 일일이 체크하면서 제거했습니다.

  17. .. | 2011-10-12 16:42

    좋은 글 잘 읽고 갑니다. :)

  18. 네옹 | 2012-06-20 15:43

    bom 때문에 며칠 고생했습니다.
    헤더에러는 나는데
    문제가 뭔지 몰라 여기 저기 헤매다 bom 이면 그 런 문제가 발생할수도있다는 해결책을 여기서 찾았습니다.
    감사합니다.

  19. 미드 | 2012-11-06 17:33

    좋은 정보 감사 드립니다. csv 파일에서 UTF-8 파일이 열리지 않아 찾고 있던 중
    좋은 글을 발견하여 해결 하게 되었네요 ^^

댓글이 닫혔습니다.