Neden Unicode'a ihtiyacımız var?
(Çok da değil) ilk günlerde var olan tek şey ASCII idi. İhtiyacınız olan tek şey birkaç cümle karakteri, noktalama işaretleri, rakamlar ve bu cümledeki gibi harflerdi. Ne yazık ki, günümüzün küresel iletişim ve sosyal medya garip dünyası öngörülmedi ve aynı belgede İngilizce, العربية, 汉语, עִבְרִית, ελληνικά ve ភាសាខ្មែរ görmek çok sıra dışı değil (umarım eski tarayıcılar).
Ancak argüman uğruna, Joe Average'un bir yazılım geliştiricisi olduğunu varsayalım. Sadece İngilizce'ye ihtiyaç duyacağı konusunda ısrar ediyor ve bu yüzden sadece ASCII kullanmak istiyor. Bu Joe kullanıcı için iyi olabilir , ama bu yazılım geliştirici Joe için iyi değil . Dünyanın yaklaşık yarısı Latin olmayan karakterler kullanıyor ve ASCII kullanmak bu insanlar için tartışmasız bir şekilde düşünüyor ve bunun üzerine yazılımını büyük ve büyüyen bir ekonomiye kapatıyor.
Bu nedenle, tüm dilleri içeren bir karakter setine ihtiyaç vardır. Böylece Unicode geldi. Her karaktere kod noktası adı verilen benzersiz bir sayı atar . Unicode'un diğer olası setlere göre bir avantajı, ilk 256 kod noktasının ISO-8859-1 ve dolayısıyla ASCII ile aynı olmasıdır. Ek olarak, yaygın olarak kullanılan karakterlerin büyük çoğunluğu, Temel Çok Dilli Düzlem (BMP) adı verilen bir bölgede sadece iki bayt ile temsil edilebilir . Şimdi bu karakter setine erişmek için bir karakter kodlaması gerekiyor ve sorunun da sorduğu gibi UTF-8 ve UTF-16'ya odaklanacağım.
Bellek hususları
Peki kaç bayt bu kodlamalarda hangi karakterlere erişim sağlıyor?
- UTF-8:
- 1 bayt: Standart ASCII
- 2 bayt: Arapça, İbranice, çoğu Avrupa alfabesi (en önemlisi Gürcüce hariç )
- 3 bayt: BMP
- 4 bayt: Tüm Unicode karakterler
- UTF-16:
- 2 bayt: BMP
- 4 bayt: Tüm Unicode karakterler
BMP'de olmayan karakterlerin eski senaryolar, matematiksel semboller, müzikal semboller ve daha nadir Çince / Japonca / Korece (CJK) karakterleri içerdiğini belirtmek gerekir .
Çoğunlukla ASCII karakterleriyle çalışacaksanız, UTF-8 kesinlikle daha fazla bellek verimlidir. Ancak, çoğunlukla Avrupa dışındaki komut dosyalarıyla çalışıyorsanız, UTF-8 kullanmak, UTF-16'dan 1,5 kat daha az bellek verimliliği sağlayabilir. Büyük web sayfaları veya uzun sözcük belgeleri gibi büyük miktarlarda metinle uğraşırken, bu durum performansı etkileyebilir.
Kodlama ile ilgili temel bilgiler
Not: UTF-8 ve UTF-16'nın nasıl kodlandığını biliyorsanız, pratik uygulamalar için bir sonraki bölüme geçin.
- UTF-8: Standart ASCII (0-127) karakterleri için UTF-8 kodları aynıdır. Bu, mevcut ASCII metni ile geriye dönük uyumluluk gerektiğinde UTF-8'i ideal hale getirir. Diğer karakterler 2-4 bayt arasında bir yere ihtiyaç duyar. Bu, çok baytlık bir karakterin parçası olduğunu belirtmek için bu baytların her birinde bazı bitler ayırarak yapılır. Özellikle, her baytın ilk biti
1
ASCII karakterleri ile çakışmadan kaçınmaktır.
- UTF-16: Geçerli BMP karakterleri için UTF-16 temsili basitçe kod noktasıdır. Bununla birlikte, BMP dışı karakterler için UTF-16 vekil çiftler sunar . Bu durumda, iki baytlık iki bölümün birleşimi BMP olmayan bir karakterle eşleşir. Bu iki baytlık kısımlar BMP sayısal aralığından gelir, ancak Unicode standardı tarafından BMP karakterleri olarak geçersiz olmaları garanti edilir. Ek olarak, UTF-16 temel birimi olarak iki bayta sahip olduğundan endianizmden etkilenir . Telafi etmek için, bir bayt sırası işareti , endianizmi gösteren bir veri akışının başına yerleştirilebilir. Bu nedenle, UTF-16 girdisini okuyorsanız ve endianness belirtilmemişse, bunu kontrol etmelisiniz.
Görülebileceği gibi, UTF-8 ve UTF-16 birbirleriyle hiçbir yere yakın değildir. G / Ç yapıyorsanız, hangi kodlamayı kullandığınızı bildiğinizden emin olun! Bu kodlamalar hakkında daha fazla bilgi için lütfen UTF SSS bölümüne bakın .
Pratik programlama hususları
Karakter ve Dize veri türleri: Programlama dilinde nasıl kodlanırlar? Ham baytlarsa, ASCII olmayan karakterler çıkarmaya çalıştığınız anda, birkaç sorunla karşılaşabilirsiniz. Ayrıca, karakter tipi bir UTF'yi temel alsa bile, bu, dizelerin uygun UTF olduğu anlamına gelmez. Yasadışı olan bayt dizilerine izin verebilirler. Genellikle, C, C ++ ve Java için ICU gibi UTF'yi destekleyen bir kütüphane kullanmanız gerekir . Her durumda, varsayılan kodlama dışında bir şey girmek / çıktısını almak istiyorsanız, önce onu dönüştürmeniz gerekir.
Önerilen / varsayılan / baskın kodlamalar: Hangi UTF'nin kullanılacağına dair bir seçenek verildiğinde, genellikle çalıştığınız ortam için önerilen standartları izlemek en iyisidir. Örneğin, UTF-8 web'de baskındır ve HTML5'ten beri olmuştur önerilen kodlama . Tersine, hem .NET hem de Java ortamları UTF-16 karakter türünde kurulmuştur. Kafa karıştırıcı (ve yanlış) olarak, genellikle belirli bir ortamda baskın UTF kodlaması anlamına gelen "Unicode kodlaması" na başvurulur.
Kütüphane desteği: Kullandığınız kütüphaneler bir tür kodlamayı destekler. Hangisi? Köşe kasalarını destekliyorlar mı? Zorunluluk buluşun anası olduğundan, UTF-8 kütüphaneleri genellikle 4 baytlık karakterleri düzgün bir şekilde destekleyecektir, çünkü 1, 2 ve hatta 3 baytlık karakterler sık sık ortaya çıkabilir. Bununla birlikte, iddia edilen UTF-16 kütüphanelerinin tümü, çok nadiren ortaya çıktıkları için vekil çiftleri düzgün bir şekilde desteklemez.
Karakterleri Sayma: Orada bulunmamakta birleştirerek Unicode karakterleri. Örneğin, kod noktası U + 006E (n) ve U + 0303 (bir birleştirici tilde) ñ oluşturur, ancak kod noktası U + 00F1 ñ oluşturur. Aynı görünmelidir, ancak basit bir sayma algoritması ilk örnek için 2, ikinci örnek için 1 döndürür. Bu mutlaka yanlış değildir, ancak istenen sonuç da olmayabilir.
Eşitlik için karşılaştırma: A, А ve Α aynı görünüyor, ancak sırasıyla Latin, Kiril ve Yunan. Ayrıca C ve Ⅽ gibi vakalarınız da var, biri harf, diğeri Romen rakamı. Ayrıca, dikkate alınması gereken birleştirici karakterlere sahibiz. Daha fazla bilgi için bkz . Unicode'da karakterleri çoğaltma .
Yedek çiftler: Bunlar SO'da yeterince sık görülür, bu yüzden sadece bazı örnek bağlantılar sağlayacağım:
Diğerleri ?: