2011-01-11 23 views
119

UTF-8 ve UTF-16 arasındaki fark nedir? Neden bunlara ihtiyacımız var?UTF-8 ve UTF-16 arasındaki fark nedir?

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

jon skeet, kodlama hakkında iyi bir makaleye sahiptir .... http: //csharpindepth.com/Articles/General/Unicode.aspx –

cevap

259

İyi makalelerin bir yeri vardır inanıyoruz Bu konuda Web etrafında, ama burada kısa bir özet.

Hem UTF-8 hem de UTF-16, değişken uzunluk kodlamalarıdır. Bununla birlikte, UTF-8'de bir karakter en az 8 bite sahipken, UTF-16 karakter uzunluğu 16 bit ile başlar.

Ana UTF-8 artıları: vb basamak gibi

  • Temel ASCII karakterleri, hiçbir desenli Latin harfleri, US-ASCII gösterimi ile aynıdır bir bayt işgal eder. Bu şekilde, tüm US-ASCII dizeleri, birçok durumda iyi geriye dönük uyumluluk sağlayan geçerli UTF-8 haline gelir.
  • Boş sonlandırılmış dizeleri kullanmanıza olanak tanıyan boş baytlar, bu da büyük ölçüde geriye dönük uyumluluk sağlar.
  • UTF-8, bayt sırasından bağımsızdır, dolayısıyla Big Endian/Little Endian sorunu hakkında endişelenmeniz gerekmez.

Ana UTF-8 eksileri:

  • Birçok ortak karakterler kod noktasıyla ve bir kod noktası korkunç saymak hesaplayarak indeksleme yavaşlatır farklı uzunluğa sahiptir.
  • Bayt sırası önemli olmasa da, bazen UTF-8, metnin UTF-8 olarak kodlandığını bildiren ve ayrıca metinle birlikte bile ASCII yazılımı ile uyumsuzluk bildiren BOM (bayt sırası işareti) içerir. ASCII karakterleri içerir. Microsoft yazılımı (Not Defteri gibi) özellikle BOM'u UTF-8'e eklemeyi seviyor.

Ana UTF-16 artıları:

  • BMP (temel dilli düzlem) karakterleri, Latin, Kiril, en Çince dahil (ÇHC BMP zorunlu dışında bazı codepoints destek yapılmış), en Japon olabilir 2 bayt ile temsil edilir.Bu, metnin ek karakterleri içermemesi durumunda kodlama sayımını ve hesaplanmasını hızlandırır.
  • Metin tamamlayıcı karakterlere sahip olsalar bile, yine de 16 bitlik değerler çiftleriyle temsil edilirler; bu, toplam uzunluğun hala iki tarafından bölünebileceği anlamına gelir ve dizenin ilkel bileşeni olarak 16 bit char kullanılmasına izin verir.

Ana UTF-16 eksileri: hayır boş sonlandırılmış dizeleri ve boşa bellek çok şey ifade US-ASCII dizeleri, null bayt

  • sürü.
  • Sabit uzunluklu bir kodlama olarak kullanmak, çoğu ortak senaryoda (çoğunlukla ABD/AB/Kiril alfabeleri/İsrail/Arap ülkeleri/İran ve diğer ülkelerde) çoğunlukla “işe yarar” olarak kodlanır. 't. Bu, programcıların vekil çiftlerin farkında olmaları ve önemli olduğu durumlarda doğru şekilde ele almaları gerektiği anlamına gelir!
  • Değişken uzunluğudur, bu nedenle UTF-8'den daha az olsa da, kod noktalarını saymak veya dizine eklemek maliyetlidir. BE/LE orada alakasız çünkü Genelde

, UTF-16 bellek temsil için genellikle daha iyidir (sadece düzgün vekil çiftleri ele unutmayın) (sadece yerli düzen kullanın) ve indeksleme hızlıdır. Öte yandan, UTF-8, metin dosyaları ve ağ protokolleri için son derece iyidir, çünkü BE/LE sorunu yoktur ve nihayet sonlandırma, ASCII uyumluluğunun yanı sıra genellikle kullanışlı hale gelir.

+1

UTF16'da sadece BE/LE parçası eksik :) UTF-8'in başka bir olumsuz yanı var. UTF16 – bestsss

+4

'dan daha uzun çıkış üretin Evet, BE/LE'yi unuttum. Özellikle de bellek içi kullanım için önemli değil. UTF-8, yalnızca üç baytlık karakterler içeriyorsa daha uzun çıkış ü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 bir çıktı üretebilir, bu nedenle dezavantaj olup olmadığı belirli bir duruma bağlıdır. –

+0

Ben utf-8, kısa boyun doğrudan pro bahsetmeden bile düşünmedim. Utf-8'in daha uzun çıktısı hakkında bir sebepten ötürü 'mayıs' olabilir, ancak hedef uzak doğu ise, varsayılan kodlama utf-16 olmalıdır. Md.update örneğinde olduğu gibi (text.getBytes ("UTF-8")); karma her iki yoldan da istikrarlı olduğundan kodlamanın önemi yoktur. – bestsss

18

Bunlar yalnızca Unicode karakterlerini temsil eden 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üzlemde (BMP) tüm karakterler için 2 bayt kullanır.

UTF-8, BMP'deki karakterler için 1 ve 3 bayt arasında, U + 0000'den U + 1FFFFF'ye kadar olan Unicode aralığındaki karakterler için 4 adede kadar kullanır ve eğer bu olursa, U + 7FFFFFFF'ye kadar genişletilebilir gerekli ... ama özellikle tüm ASCII karakterleri her biri tek bir bayt olarak gösterilir.

Bir ileti sindirmek amacıyla, hangisini seçerseniz, sindirmeyi yeniden başlatmayı deneyen herkes aynı seçeneği kullandığı sürece önemli değildir.

UTF-8 ve Unicode hakkında daha fazla bilgi için this page'a bakın.

(tüm Java karakterleri UTF-16 BMP içinde kod noktaları olduğunu unutmayın;. Eğer Java vekil çiftleri kullanmak zorunda U + FFFF yukarıdaki karakterleri temsil etmek)

4

Bu, UTF-8/16 ile ilgisi yoktur (genel olarak, UTF16'ya dönüştürülse ve BE/LE kısmı tek bir satır olarak ayarlanabilse de), ancak aşağıdaki dize byte dönüştürmenin en hızlı yoludur []. Örneğin: sağlanan dava için tam olarak (hash 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; 
    } 
0

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

Belirtilen karakterle aynı unicode numarasını paylaşmanın dışında, her biri kendi biçimidir.

İlgili konular