Skip to content

Byte order mark

바이트 순서 표식(Byte Order Mark, BOM)은 유니코드에서 엔디안을 구별하기 위해 사용되는 문자로, 문자 값은 U+FEFF이다.

UTF-16, UTF-32와 같은 인코딩에서는 엔디안의 종류에 따라 문자열의 값이 완전히 달라지므로, 문자열의 엔디안을 구별할 수 있는 표식이 필요하다. 이에 따라 유니코드 문자열 앞에 BOM 문자를 붙여, 맨 처음에 읽히는 값에 따라 엔디안을 구별한다.

예를 들어, UTF-16에서 빅 엔디안의 경우에 문자열의 가장 처음 두 바이트는 FE FF가 된다. 리틀 엔디안의 경우에는 FF FE가 된다.

BOM

각 유니코드 인코딩 방법에 따른 BOM 값은 다음과 같다.

Encoding

Representation

UTF-8

EF BB BF

UTF-16 빅 엔디안

FE FF

UTF-16 리틀 엔디안

FF FE

UTF-32 빅 엔디안

00 00 FE FF

UTF-32 리틀 엔디안

FF FE 00 00

SCSU

0E FE FF

UTF-EBCDIC

DD 73 66 73

BOCU-1

FB EE 28

VIM 에서 BOM 확인 방법

참고로 vim에서 확인하면 다음과 같다:

Byte_order_mark_-vim-_text.png

<feff> 로 출력되어, UTF-16 빅엔디언 BOM 처럼 보이지만

이걸 xxd(vim 명령은 :%!xxd 이다)으로 확인하면 다음과 같이 첫 세 바이트에 BOM 바이트가 보인다:

Byte_order_mark_-vim-_xxd.png

ef bb bf이므로 UTF-8 BOM 이다.

그래서 VIM 에서는 BOM 출력 오류를 주의해야 한다.

UTF-8 BOM 제거 스크립트

UTF-8 BOM (ef bb bf)을 제거하는 bash 스크립트는 다음과 같다:

#!/bin/bash

# 디렉토리를 재귀적으로 탐색하면서 파일 목록을 얻는 함수
function find_files() {
    local dir=$1
    find "$dir" -type f
}

# 파일의 BOM(Byte Order Mark)을 제거하는 함수
function remove_bom() {
    local file=$1
    if [[ $(head -c3 "$file") == $'\xef\xbb\xbf' ]]; then
        tail -c +4 "$file" > "${file}.tmp"
        mv "${file}.tmp" "$file"
    fi
}

# 디렉토리에서 파일을 찾아서 BOM을 제거하는 함수
function remove_bom_recursive() {
    local dir=$1
    for file in $(find_files "$dir"); do
        remove_bom "$file"
    done
}

# 스크립트 실행 시작
if [[ -n "$1" ]]; then
    # 첫 번째 인자로 전달된 디렉토리에서 BOM 제거 시작
    remove_bom_recursive "$1"
else
    # 현재 디렉토리에서 BOM 제거 시작
    remove_bom_recursive .
fi

Favorite site