이 페이지의 선택한 이전 버전과 현재 버전 사이의 차이점을 보여줍니다.
utf-8 [2011-03-31 06:19] lifthrasiir 새로 만듦 |
utf-8 [2012-01-26 22:50] (현재) lifthrasiir 정정: utf-8-bom -> utf-8-sig |
||
---|---|---|---|
줄 1: | 줄 1: | ||
====== UTF-8 ====== | ====== UTF-8 ====== | ||
- | [[유니코드]] [[문자인코딩]]((The Unicode Standard, Version 6.0, [[http://www.unicode.org/versions/Unicode6.0.0/ch02.pdf|Section 2.5]] (pp. 27--28).)). UTF는 "[[국제문자집합|UCS]] 변환 포맷"으로 전송·저장에 적합한 표현 방법을 이르는데, UTF-8은 그 중에서도 가장 널리 쓰이는 축에 속한다. | + | 8-bit [[국제문자집합|UCS]] Transformation Format (8비트 국제 문자 집합 변환 포맷). |
+ | [[유니코드]] [[문자인코딩]]((The Unicode Standard, Version 6.0, [[http://www.unicode.org/versions/Unicode6.0.0/ch02.pdf|Section 2.5]] (pp. 27--28).)). UTF는 전송·저장에 적합한 유니코드의 표현 방법을 이르는데, UTF-8은 그 중에서도 가장 널리 쓰이는 축에 속한다. | ||
[[Ken Thompson]]과 [[Rob Pike]]가 [[Plan 9]]에서 사용할 목적으로---그래서 원래 이름은 **FSS-UTF**(File System Safe UTF)이었다---만들었는데 그 설계가 매우 깔끔하고 효율적이라 온갖 곳에서 다 쓰이고 있다. 보통 메모리 상에 들어 있는 유니코드 문자열([[UTF-16]]이나 [[UTF-32]]인 경우가 대부분) 빼고는 다 UTF-8을 써도 된다고 해도 과언이 아닐 정도. [[웹]]에서도 웬만한 기존 문자 인코딩보다 많이 쓰이고(([[구글]]에 따르면 [[http://googleblog.blogspot.com/2008/05/moving-to-unicode-51.html|2007년 말]]에 과반수를 넘었다.)) 기존 문자 인코딩의 흔한 문제점([[깨진문자]] 등)을 해결할 수 있어서 꾸준히 대체되는 추세. | [[Ken Thompson]]과 [[Rob Pike]]가 [[Plan 9]]에서 사용할 목적으로---그래서 원래 이름은 **FSS-UTF**(File System Safe UTF)이었다---만들었는데 그 설계가 매우 깔끔하고 효율적이라 온갖 곳에서 다 쓰이고 있다. 보통 메모리 상에 들어 있는 유니코드 문자열([[UTF-16]]이나 [[UTF-32]]인 경우가 대부분) 빼고는 다 UTF-8을 써도 된다고 해도 과언이 아닐 정도. [[웹]]에서도 웬만한 기존 문자 인코딩보다 많이 쓰이고(([[구글]]에 따르면 [[http://googleblog.blogspot.com/2008/05/moving-to-unicode-51.html|2007년 말]]에 과반수를 넘었다.)) 기존 문자 인코딩의 흔한 문제점([[깨진문자]] 등)을 해결할 수 있어서 꾸준히 대체되는 추세. | ||
줄 18: | 줄 19: | ||
반대로, 각 바이트가 문자의 어떤 부분인지는 비트 패턴을 보고 파악할 수 있다: | 반대로, 각 바이트가 문자의 어떤 부분인지는 비트 패턴을 보고 파악할 수 있다: | ||
- | ^ 비트 패턴 ^ 설명 ^ | + | ^ 비트 패턴 ^ 바이트 범위 ^ 설명 ^ |
- | | **''0xxxxxxx''** | 코드 포인트 ''0xxxxxxx''. | | + | | **''0xxxxxxx''** | ''00'' - ''7F'' | 코드 포인트 ''0xxxxxxx''. | |
- | | **''10xxxxxx''** | ''110xxxxx'', ''1110xxxx'' 및 ''11110xxx'' 바이트 다음에 나오는 "나머지" 바이트. 한 개의 나머지 바이트는 코드 포인트의 6비트를 인코딩한다. | | + | | **''10xxxxxx''** | ''80'' - ''BF'' | ''110xxxxx'', ''1110xxxx'' 및 ''11110xxx'' 바이트 다음에 나오는 "나머지" 바이트. 한 개의 나머지 바이트는 코드 포인트의 6비트를 인코딩한다. | |
- | | **''110xxxyy''** | 코드 포인트 ''%%00000xxx yy......%%''의 시작. 한 개의 나머지 바이트가따라 온다. | | + | | **''110xxxyy''** | ''C0'' - ''DF'' | 코드 포인트 ''%%00000xxx yy......%%''의 시작. 한 개의 나머지 바이트가 따라온다. | |
- | | **''1110xxxx''** | 코드 포인트 ''%%xxxx.... ........%%''의 시작. 두 개의 나머지 바이트가 따라온다. | | + | | **''1110xxxx''** | ''E0'' - ''EF'' | 코드 포인트 ''%%xxxx.... ........%%''의 시작. 두 개의 나머지 바이트가 따라온다. | |
- | | **''11110xxx''** | 코드 포인트 ''%%000xxx.. ........ ........%%''의 시작. 세 개의 나머지 바이트가 따라온다. | | + | | **''11110xxx''** | ''F0'' - ''F7'' | 코드 포인트 ''%%000xxx.. ........ ........%%''의 시작. 세 개의 나머지 바이트가 따라온다. | |
- | | **''11111xxx''** | (사용하지 않음) | | + | | **''11111xxx''** | ''F8'' - ''FF'' | (사용하지 않음) | |
- | 추가 규칙으로, U+0000 같은 경우 기본적으로는 ''00'', ''C0 80'', ''D0 80 80'', ''F0 80 80 80'' 같은 여러 가지 방법으로 인코딩될 수 있지만 이 중 가장 짧은 ''00''만이 올바른 UTF-8 표현이 된다. 따라서 바이트 ''80''(U+0000~003F에 대응), ''81''(U+0040~007F에 대응)은 실제로는 나타날 수 없으며, 바이트 ''D0'' 뒤에는 ''80''부터 ''9F''까지의 바이트는 올 수 없는(U+0000~07FF에 대응) 등의 제약이 따라 붙는다. 기술적으로 말하면 [[유니코드서로게이트영역|서로게이트]] 문자도 오면 안 되는데, 현실에서는 안 그런 경우도 있다([[#수정 UTF-8]] 참고). | + | 추가 규칙으로, U+0000 같은 경우 기본적으로는 ''00'', ''C0 80'', ''D0 80 80'', ''F0 80 80 80'' 같은 여러 가지 방법으로 인코딩될 수 있지만 이 중 가장 짧은 ''00''만이 올바른 UTF-8 표현이 된다. 따라서 실제로는 다음과 같은 제약이 추가된다: |
+ | |||
+ | * 바이트 ''80''(U+0000~003F에 대응)과 ''81''(U+0040~007F에 대응)은 사용하지 않는다. | ||
+ | * 바이트 ''D0'' 뒤에는 ''80''부터 ''9F''까지의 바이트가 올 수 없다(U+0000~07FF에 대응). | ||
+ | * 바이트 ''F0'' 뒤에는 ''80''부터 ''8F''까지의 바이트가 올 수 없다(U+0000~FFFF에 대응). | ||
+ | * 바이트 ''F4'' 뒤에는 ''90''부터 ''BF''까지의 바이트가 올 수 없다(U+110000~13FFFF에 대응). | ||
+ | * 바이트 ''F5''(U+140000~17FFFF에 대응)부터 ''F7''(U+1C0000~1FFFFF에 대응)까지는 사용하지 않는다. | ||
+ | |||
+ | 결과적으로 모든 유니코드 문자열은 정확히 하나의 올바른 UTF-8 표현을 갖는다. (종종 이 성질을 무시하고 대강 구현하는 경우가 있는데 십중팔구 [[보안취약점]]으로 자주 깨지곤 한다...) 기술적으로 말하면 [[유니코드서로게이트영역|서로게이트]] 문자도 오면 안 되는데, 현실에서는 안 그런 경우도 있다([[#수정 UTF-8]] 참고). | ||
==== 설계 원칙 ==== | ==== 설계 원칙 ==== | ||
줄 33: | 줄 42: | ||
* U+0000부터 U+007F까지는 [[ASCII]] 및 그에 기반한 다양한 8비트 [[문자인코딩]]과 호환된다. 따라서 ASCII만 쓰는 경우 대응되는 UTF-8 문자열은 변환이 필요 없다! | * U+0000부터 U+007F까지는 [[ASCII]] 및 그에 기반한 다양한 8비트 [[문자인코딩]]과 호환된다. 따라서 ASCII만 쓰는 경우 대응되는 UTF-8 문자열은 변환이 필요 없다! | ||
- | * 문자열 안에 U+0000이 들어 가지 않는다면 UTF-8 문자열은 [[C]]의 [[널로끝나는문자열]]로 그대로 사용할 수 있다. 따라서 [[파일시스템]]을 비롯해 널 문자가 들어 가면 엉망이 되는 기존 시스템에 수정 없이 사용할 수 있다. | + | * 문자열 안에 U+0000이 들어 가지 않는다면 UTF-8 문자열은 [[C언어]]의 [[널로끝나는문자열]]로 그대로 사용할 수 있다. 따라서 [[파일시스템]]을 비롯해 널 문자가 들어 가면 엉망이 되는 기존 시스템에 수정 없이 사용할 수 있다. |
* 인코딩 및 디코딩은 [[비트연산]] 몇 개만으로 쉽게 할 수 있다. UTF-8이 처음 나오던 당시 고려되던 가변 길이 인코딩은 1~5바이트를 사용하는 [[UTF-1]]이었으나 느린 나눗셈 연산을 사용해야 하는 문제가 있었다. | * 인코딩 및 디코딩은 [[비트연산]] 몇 개만으로 쉽게 할 수 있다. UTF-8이 처음 나오던 당시 고려되던 가변 길이 인코딩은 1~5바이트를 사용하는 [[UTF-1]]이었으나 느린 나눗셈 연산을 사용해야 하는 문제가 있었다. | ||
* 각 코드포인트의 처음에 올 수 있는 바이트와 그 뒤에 올 수 있는 바이트가 명확히 구분되어 있다. | * 각 코드포인트의 처음에 올 수 있는 바이트와 그 뒤에 올 수 있는 바이트가 명확히 구분되어 있다. | ||
줄 58: | 줄 67: | ||
* 유닉스 [[셔뱅]] 파일은 파일의 맨 첫 두 바이트가 ''#!''여야 하는데, 바이트 순서 마크가 있으면 그 조건이 깨져서 동작하지 않게 된다. | * 유닉스 [[셔뱅]] 파일은 파일의 맨 첫 두 바이트가 ''#!''여야 하는데, 바이트 순서 마크가 있으면 그 조건이 깨져서 동작하지 않게 된다. | ||
- | 그러하니 제발 좀 쓰지 말자. 참고로 [[vim]]과 [[파이썬]]에서는 UTF-8 바이트 순서 마크를 필요로 하는 <del>거지같은</del> 상황을 위하여 ''utf-8-bom'' 인코딩을 별도로 제공하고 있긴 하다. | + | 그러하니 제발 좀 쓰지 말자. 참고로 [[vim]]과 [[파이썬]]에서는 UTF-8 바이트 순서 마크를 필요로 하는 <del>거지같은</del> 상황을 위하여 각각 ''%%'bomb'%%'' 옵션(...)과 ''utf-8-sig'' 인코딩을 별도로 제공하고 있긴 하다. |
==== 수정 UTF-8 ==== | ==== 수정 UTF-8 ==== |