UTF-8과 UTF-16의 차이점은 무엇입니까?


137

UTF-8과 UTF-16의 차이점은 무엇입니까? 왜 우리는 이것들이 필요합니까?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();

2
존 소총은 .... 인코딩에 좋은 기사를 가지고 csharpindepth.com/Articles/General/Unicode.aspx
미치 밀

답변:


284

웹에 대한 좋은 기사가 많이 있다고 생각하지만 여기에 간단한 요약이 있습니다.

UTF-8과 UTF-16은 모두 가변 길이 인코딩입니다. 그러나 UTF-8에서 문자는 최소 8 비트를 차지할 수 있지만 UTF-16에서 문자 길이는 16 비트로 시작합니다.

주요 UTF-8 전문가 :

  • 숫자, 악센트가없는 라틴 문자 등과 같은 기본 ASCII 문자는 US-ASCII 표현과 동일한 1 바이트를 차지합니다. 이런 식으로 모든 US-ASCII 문자열이 유효한 UTF-8이되어 많은 경우에 하위 호환성을 제공합니다.
  • null로 끝나지 않는 문자열을 사용할 수있는 null 바이트가 없으므로 이전 버전과의 호환성도 매우 뛰어납니다.
  • UTF-8은 바이트 순서와 무관하므로 Big Endian / Little Endian 문제에 대해 걱정할 필요가 없습니다.

주요 UTF-8 단점 :

  • 많은 공통 문자의 길이가 다르기 때문에 코드 포인트별로 인덱싱하고 코드 포인트 수를 계산하는 데 시간이 많이 걸립니다.
  • 바이트 순서는 중요하지 않지만 때때로 UTF-8에는 텍스트가 UTF-8로 인코딩되었음을 알리고 ASCII 문자 만 포함하더라도 ASCII 소프트웨어와의 호환성을 손상시키는 BOM (바이트 순서 표시)이 여전히 있습니다 . 메모장과 같은 Microsoft 소프트웨어는 특히 UTF-8에 BOM을 추가하는 것을 좋아합니다.

주요 UTF-16 전문가 :

  • 라틴어, 키릴 자모, 대부분의 중국어 (PRC가 BMP 이외의 일부 코드 포인트를 지원함)를 포함한 BMP (기본 다국어 평면) 문자, 대부분의 일본어는 2 바이트로 표현할 수 있습니다. 텍스트에 추가 문자가 포함 되지 않은 경우 색인 작성 및 코드 포인트 수를 빠르게합니다 .
  • 텍스트에 보충 문자가 있어도 16 비트 값의 쌍으로 표시됩니다. 즉, 전체 길이는 여전히 2로 나눌 수 있으며 16 비트 char를 문자열의 기본 구성 요소로 사용할 수 있습니다 .

주요 UTF-16 단점 :

  • US-ASCII 문자열에 널 바이트가 많으므로 널 (null)로 끝나는 문자열이없고 낭비되는 메모리가 많습니다.
  • 고정 길이 인코딩으로 사용하면 많은 일반적인 시나리오 (특히 미국 / EU / 키릴 자모가있는 국가 / 이스라엘 / 아랍 국가 /이란 등)에서 "대부분 작동"하므로 종종 지원하지 않는 곳에서 지원이 중단됩니다. 이는 프로그래머가 서로 게이트 쌍을 인식하고 중요한 경우 올바르게 처리해야 함을 의미합니다!
  • 가변 길이이므로 코드 포인트의 수를 계산하거나 인덱싱하는 데 비용이 많이 들지만 UTF-8보다 적습니다.

일반적으로 UTF-16은 BE / LE가 관련이없고 (기본 순서 만 사용) 인덱싱이 더 빠르기 때문에 (대리 쌍을 올바르게 처리하는 것을 잊지 마십시오) 일반적으로 인 메모리 표현에 더 좋습니다. 반면에 UTF-8은 BE / LE 문제가없고 널 종료가 종종 ASCII 호환뿐만 아니라 텍스트 파일 및 네트워크 프로토콜에 매우 유용합니다.


3
UTF16에만 BE / LE 부분을 누락 : UTF-8은 또 다른 단점이있다, 그것은 UTF16 이상 출력을 생성 할 수
bestsss

4
예, BE / LE를 잊었습니다. 그러나 특히 메모리 내 사용에 큰 문제는 아닙니다. UTF-8은 3 바이트 문자가 관련된 경우에만 더 긴 출력을 생성하지만 대부분 중국어와 일본어를 의미합니다. 반면에 텍스트에 US-ASCII 문자가 많이 포함되어 있으면 출력이 더 짧아 질 수 있으므로 단점인지 여부는 특정 상황에 따라 다릅니다.
Sergei Tachenov

나는 짧은 길이의 utf-8의 즉각적인 프로에 대해서는 언급조차하지 않았다. utf-8의 더 긴 출력에 대해서는 이유가 '아마도'일 수 있지만, 대상이 멀리 동쪽이면 기본 인코딩은 utf-16이어야합니다. 예를 들어 md.update (text.getBytes ( "UTF-8")); 해시는 양방향으로 안정적이므로 인코딩은 중요하지 않습니다.
bestsss

문자열을 바이트 배열로 변환하는 가장 빠른 방법은 샘플로 게시 된 것과 같은 것입니다
bestsss

UTF-8의 문자 길이가 다르기 때문에 인덱싱 및 길이 계산 속도가 느려지지만 UTF-16의 문자 길이가 다른지 의심됩니다.
nicky_zs

19

유니 코드 문자를 나타내는 다른 방식 일뿐입니다.

둘 다 가변 길이입니다. UTF-16은 기본 다국어 플레인 (BMP)의 모든 문자에 2 바이트를 사용하며 대부분의 문자는 일반적으로 사용됩니다.

UTF-8은 BMP의 문자에 1에서 3 바이트를 사용하고 U + 0000에서 U + 1FFFFF까지의 현재 유니 코드 범위의 문자에 대해 최대 4 바이트를 사용하며 필요한 경우 U + 7FFFFFFF까지 확장 할 수 있습니다. 그러나 모든 ASCII 문자는 각각 단일 바이트로 표시됩니다.

메시지 다이제스트의 목적으로 다이제스트를 다시 만들려고하는 모든 사람이 동일한 옵션을 사용하는 한 어떤 것을 선택하든 상관 없습니다.

UTF-8 및 유니 코드에 대한 자세한 내용은 이 페이지 를 참조하십시오 .

(모든 Java 문자는 BMP 내의 UTF-16 코드 포인트입니다. U + FFFF보다 높은 문자를 나타내려면 Java에서 서로 게이트 쌍을 사용해야합니다.)


5

보안 : UTF-8 만 사용

UTF-8과 UTF-16의 차이점은 무엇입니까? 왜 우리는 이것들이 필요합니까?

UTF-16 구현에는 적어도 몇 가지 보안 취약점이있었습니다 . 자세한 내용은 Wikipedia를 참조하십시오 .

WHATWGW3C이제 UTF-8 만 웹에서 사용되도록 선언 했습니다 .

여기에 요약 된 [security] 문제는 UTF-8을 독점적으로 사용할 때 사라집니다. 이는 이제 모든 것에 대한 필수 인코딩 인 여러 가지 이유 중 하나입니다.

다른 그룹들도 같은 말을하고 있습니다.

따라서 UTF-16이 Java 및 Windows와 같은 일부 시스템에서 계속 내부적으로 사용될 수 있지만 데이터 파일, 데이터 교환 등에서 과거에 보았던 UTF-16의 사용은 거의 사라질 것입니다.


4

이것은 UTF-8 / 16과 관련이 없습니다 (일반적으로 UTF16으로 변환하고 BE / LE 부분을 한 줄로 설정할 수 있지만) 아래는 String을 byte []로 변환하는 가장 빠른 방법입니다. 예를 들어, 제공된 사례에 정확히 맞습니다 (해시 코드). String.getBytes (enc)는 상대적으로 느립니다.

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }

-2

UTF-8과 UTF-16을 구별하는 간단한 방법은 이들 사이의 공통성을 식별하는 것입니다.

주어진 문자에 대해 동일한 유니 코드 번호를 공유하는 것 외에 각각 고유 한 형식입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.