Table of Contents
UTF-16을 정의하는 ietf문서#
http://www.ietf.org/rfc/rfc2781.txt
UTF-16 정의#
UTF-16은 버전 3.0에서 유니코드 표준으로 지정되었다.- 0x10000 ( 16진수로는 65536, 2진수로는 11111111 11111111 + 1 ) 보다 작은 문자들은 한개의 16비트 숫자로 표기된다.
- 0x10000 와 0x10FFFF 사이의 값을 가지는 문자들은 0xD800 와 0xDBFF 사이의 값을 가지는 16비트 숫자와 0xDC00 와 0xDFFF 사이의 값을 가지는 16비트 숫자로 표기된다.
Bit 31 24|23 16|15 8|7 0| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0 0 0 0 0 0 0 0|0 0 0 z z z z z|x x x x x x y y|y y y y y y y y| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |15 8|7 0| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1 1 0 1 1 0 Z Z|Z Z x x x x x x| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |15 8|7 0| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1 1 0 1 1 1 y y|y y y y y y y y| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 0x10FFFF 보다 큰 값은 UTF-16으로 인코딩 할수 없다.
0xD800 와 0xDFFF 사이의 값들이 특별히 UTF-8 를 사용하도록 예약되어 있다.
UTF-16 인코딩/디코딩#
인코딩#
- 0x10000 보다 작다면 16 비트 unsigned 정수로 인코딩되고 종료된다.
- 0x10000 을 빼서 0xFFFFF 보다 작거나 같다면 20비트 문자로 표기할 수 있다.
U' = yyyyyyyyyyxxxxxxxxxx W1 = 110110yyyyyyyyyy W2 = 110111xxxxxxxxxx
디코딩#
자바를 이용해 UTF-16 으로 문자을 추출해보면 대상이 되는 문자는 2개의 char로 추출이 된다. 각각을 W1, W2 라고 할때.- W1 < 0xD800 또는 W1 > 0xDFFF 라면 U는 W1이 된다.
- W1이 0xD800 와 0xDBFF 사이의 값이 아니라면 에러이다.
- W2가 없거나 W2가 0xDC00 와 0xDFFF 사이의 값이라면 에러이다.
- 20비트의 unsigned 정수 U' 로 만들고 W1, W2에서 10비트씩 값을 가져와서 만든다.
- 실제 값을 얻기 위해 0x10000 를 더하고 값을 추출한다.
public String encode(String content, int start, int end) { StringBuilder sgml = new StringBuilder(); char chr, chr2; int ord = 0; for (int i = 0; i < content.length(); i++) { chr = content.charAt(i); ord = (int) chr; if ( (int) chr > 55296 || (int) chr < 57343 ) { if ( (int) chr > 55296 && (int) chr < 56319 ) { chr2 = content.charAt(i+1); if ( (int) chr2 > 56320 && (int) chr < 57343) { ord = (int) ((int) (chr & 1023) << 10) + (int) (chr2 & 1023) + 65536; i = i + 1; } else { //error } } else { //error } } if (start <= ord && ord <= end) { sgml.append(prefix + ord + suffix); } else { sgml.append(chr); } } return sgml.toString(); } public String decode(String sgml) { StringBuilder content = new StringBuilder(); StringBuilder buffer = new StringBuilder(); int ord = 0, chr = 0, status = 0; for (int i = 0; i < sgml.length(); i++) { ord = (int)sgml.charAt(i); // & 일 경우 if (ord == 38) { status = 1; buffer.append((char) ord); // # 일 경우 } else if (status == 1 && ord == 35) { status = 2; buffer.append((char) ord); // 0-9 일 경우 } else if ((status == 2 || status == 3) && ( 47 < ord && ord < 58 ) ) { status = 3; buffer.append((char) ord); // ; 일 경우 } else if (status == 3 && ord == 59 ) { status = 0; chr = Integer.parseInt(buffer.substring(2, buffer.length())); if ( chr < 65536 ) { content.append((char) chr); } else { chr = chr - 65536; content.append((char) ((chr >> 10) | 55296)); content.append((char) ((chr & 1023) | 56320)); } buffer.delete(0, buffer.length()); // 아무것도 아닐경우 } else { status = 0; content.append(buffer); buffer.delete(0, buffer.length()); } } return content.toString(); }
Add new attachment
Only authorized users are allowed to upload new attachments.
G’day (anonymous guest)
My Prefs