UTF-8 ve UTF-16 arasındaki fark nedir?


Yanıtlar:


284

Web'de bununla ilgili birçok iyi makale olduğuna inanıyorum, ancak kısa bir özet.

Hem UTF-8 hem de UTF-16 değişken uzunluklu kodlamalardır. Bununla birlikte, UTF-8'de bir karakter en az 8 bit içerebilirken, UTF-16'da karakter uzunluğu 16 bit ile başlar.

Ana UTF-8 profesyonelleri:

  • Rakamlar, aksasız Latin karakterler vb. Gibi temel ASCII karakterleri, US-ASCII gösterimi ile aynı olan bir bayt içerir. Bu şekilde tüm US-ASCII dizeleri geçerli UTF-8 olur ve bu da birçok durumda geriye dönük iyi uyumluluk sağlar.
  • Boş sonlandırılmış dizelerin kullanılmasına izin veren boş bayt yok, bu da geriye dönük uyumluluk sağlar.
  • UTF-8 bayt sırasından bağımsızdır, bu nedenle Big Endian / Little Endian sorunu hakkında endişelenmenize gerek yoktur.

Ana UTF-8 eksileri:

  • Birçok ortak karakterin uzunluğu farklıdır, bu da kod noktasına göre endekslemeyi yavaşlatır ve kod noktası sayısını çok hesaplar.
  • Bayt sırası önemli olmasa da, bazen UTF-8'de metnin UTF-8'de kodlandığını bildiren BOM (bayt sırası işareti) vardır ve metin yalnızca ASCII karakterleri olsa bile ASCII yazılımı ile uyumluluğu bozar . Microsoft yazılımı (Not Defteri gibi) özellikle UTF-8'e BOM eklemeyi sever.

Ana UTF-16 artıları:

  • Latince, Kiril, çoğu Çince (PRC, BMP dışındaki bazı kod noktalarını destekledi) dahil olmak üzere BMP (temel çok dilli uçak) karakterleri, çoğu Japonca 2 bayt ile temsil edilebilir. Bu hızlar endeksleme yukarı ve hesaplama codepoint sayım metin yapar durumda değil tamamlayıcı karakterler içerir.
  • Metin ek karakterlere sahip olsa bile, yine de 16 bitlik değer çiftleri ile temsil edilir, bu da toplam uzunluğun hala iki ile bölünebilir charve dizenin ilkel bileşeni olarak 16 bit kullanılmasına izin verir .

Ana UTF-16 eksileri:

  • US-ASCII dizelerinde çok sayıda boş bayt, yani boş sonlandırılmış dizeler ve çok fazla boşa giden bellek anlamına gelir.
  • Bunu sabit uzunluklu kodlama olarak “çoğunlukla işe yarıyor” gibi birçok yaygın senaryoda (özellikle ABD / AB / Kiril alfabesi bulunan / İsrail / Arap ülkeleri / İran ve diğer birçok ülkede), çoğu zaman desteklemediği yerlerde desteğin kırılmasına yol açar. Bu, programcıların vekil çiftlerin farkında olması ve önemli durumlarda bunları doğru şekilde işlemesi gerektiği anlamına gelir!
  • Değişken uzunluktadır, bu nedenle UTF-8'den daha az olsa da kod noktalarını saymak veya endekslemek maliyetlidir.

Genel olarak, UTF-16 genellikle bellek içi gösterim için daha iyidir, çünkü BE / LE orada ilgisizdir (sadece yerel sipariş kullanın) ve indeksleme daha hızlıdır (sadece vekil çiftleri doğru şekilde işlemeyi unutmayın). Öte yandan UTF-8, metin dosyaları ve ağ protokolleri için son derece iyidir, çünkü BE / LE sorunu yoktur ve boş sonlandırma ASCII uyumluluğunun yanı sıra kullanışlı olur.


3
UTF16'da sadece BE / LE kısmı eksik :) UTF-8'in başka bir dezavantajı var,
UTF16'dan

4
Evet, BE / LE'yi unuttum. Yine de, özellikle bellek içi kullanım için çok önemli değil. UTF-8, yalnızca üç baytlık karakterler varsa daha uzun çıktı üretecektir, ancak bu çoğunlukla Çince ve Japonca anlamına gelir. Öte yandan, metin çok sayıda US-ASCII karakteri içeriyorsa, daha kısa çıktı üretebilir, bu nedenle dezavantajlı olup olmadığı belirli bir duruma bağlıdır.
Sergei Tachenov

Utf-8'in hemen yanlısı, daha kısa uzunluğundan bahsetmeyi bile düşünmedim. Utf-8'in daha uzun çıktısı için bir sebepten ötürü 'olabilir', ancak hedef uzak doğu ise, varsayılan kodlama utf-16 olmalıdır. Örnek md.update (text.getBytes ("UTF-8")); her iki yönde de karma olduğu için kodlamanın önemi yoktur.
bestsss

String'i bayt dizisine dönüştürmenin en hızlı yolu böyle bir şeydir, örnek olarak yayınlanmıştır
bestsss

Karakterlerin UTF-8'de farklı uzunlukları olduğunu söylüyorsunuz, bu nedenle indeksleme ve hesaplama uzunluğunu yavaşlatıyor, ancak UTF-16'daki karakterlerin de farklı uzunlukları olduğundan şüpheliyim, UTF-16'nın indekslenmesi ve hesaplanması daha hızlı olmalı mı?
nicky_zs

19

Unicode karakterleri temsil etmek için farklı şemalardır.

Her ikisi de değişken uzunluktadır - UTF-16, ortak kullanımda çoğu karakteri içeren temel çok dilli düzlemdeki (BMP) tüm karakterler için 2 bayt kullanır.

UTF-8, BMP'deki karakterler için 1 ila 3 bayt, mevcut U + 0000 ila U + 1FFFFF arasındaki Unicode karakterleri için 4'e kadar kullanır ve gerektiğinde U + 7FFFFFFF'ye kadar genişletilebilir ... ancak özellikle tüm ASCII karakterleri her biri tek bir baytta gösterilir.

Bir mesaj özeti amacıyla, özeti yeniden oluşturmaya çalışan herkes aynı seçeneği kullandığı sürece bunlardan hangisini seçtiğiniz önemli değildir.

Bu sayfaya bakınUTF-8 ve Unicode hakkında daha fazla bilgi için .

(Tüm Java karakterlerinin BMP içindeki UTF-16 kod noktaları olduğunu unutmayın; U + FFFF üzerindeki karakterleri temsil etmek için Java'da yedek çiftler kullanmanız gerekir.)


5

Güvenlik: Yalnızca UTF-8 kullanın

UTF-8 ve UTF-16 arasındaki fark nedir? Bunlara neden ihtiyacımız var?

UTF-16 uygulamalarında en az birkaç güvenlik açığı bulunmaktadır . Ayrıntılar için Wikipedia'ya bakın .

WHATWG ve W3C var şimdi beyan yalnızca bu UTF-8 Web'de kullanılacak.

Burada özetlenen [güvenlik] sorunları, yalnızca her şey için zorunlu kodlama olan birçok nedenden biri olan UTF-8 kullanıldığında ortadan kalkar.

Diğer gruplar da aynı şeyi söylüyor.

Bu nedenle UTF-16, Java ve Windows gibi bazı sistemler tarafından dahili olarak kullanılmaya devam ederken, geçmişte veri dosyaları, veri alışverişi ve benzeri için ne kadar az UTF-16 kullanmış olabileceğiniz büyük olasılıkla tamamen kaybolur.


4

Bu UTF-8/16 ile ilgisizdir (genel olarak UTF16'ya dönüşmesine ve BE / LE kısmı tek bir satırla ayarlanabilir), ancak String'i byte [] 'a dönüştürmenin en hızlı yolu aşağıdadır. Örneğin: tam olarak sağlanan durum için iyi (karma kodu). String.getBytes (enc) nispeten yavaştır.

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

-3

UTF-8 ve UTF-16'yı ayırt etmenin basit yolu, aralarındaki ortaklıkları tanımlamaktır.

Verilen karakter için aynı unicode numarasını paylaşmak dışında, her biri kendi biçimidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.