Neden birden fazla Unicode kodlaması var?


41

Unicode'un, önceki girişimlerin çoğunda (ASCII, vb.) Küçük bir adres alanı (8 bit) nedeniyle birçok farklı kodlamanın tüm sorununu çözecek şekilde tasarlandığını düşündüm.

Öyleyse neden bu kadar çok Unicode kodlaması var? UTF-8, UTF-16, vs. gibi (esasen) aynı olanın birden fazla versiyonu bile


11
UTF-8, UTF-16 ile aynı değildir. Liste, dünya benzeri gezegenlere sahip diğer güneş sistemleriyle karşılaştığımız zaman büyüyecek.
setzamora

1
@Joset: Zaten Klingon'umuz var. BMP'de pek çok dünya diline sahibiz, ovalara 1,2. Mevcut işler doğruysa ve galakside yalnızca uzay yolculuğunu kullanabilecekleri bir noktaya ulaşan (dolayısıyla ilk temasa izin veren) 42 canlı tür varsa, tüm dillerdeki tüm karakterleri UNICODE'ye kadar sıkıştırabiliriz (genişletebileceğimizi varsayalım) 64 ova izin vermek için 21 ila 22 bit). Uzay uçuşu sağlamayan ilkel türleri dahil etmek istiyorsak, bu bile 10 bit tampon alanı bırakır.
Martin York

7
Kevin Hsu: UTF-7,8,16LE, 16BE, 32LE, 32BE. Yani, en az 6 gerçek kodlama var. UTF-9 ve UTF-18 Nisan Şakasıdır.
MSalters

9
Standartlarla ilgili iyi bir şey, birçoğunun var olduğu
Homde

1
Spolsky'nin Unicode ve kodlama konusunda neler söylediğini görün .
MPelletier

Yanıtlar:


29

Çünkü insanlar her karakter için 21 bit harcamak istemiyorlar. Tüm modern sistemlerde, bu, esasen, insanların alışkın olduklarından üç kat daha fazla olan karakter başına üç bayt kullanmak anlamına gelir, bu yüzden Unicode'u benimseme konusunda isteksizdiler. Uzlaşmaların bulunması gerekiyordu: örneğin UTF-8 İngilizce metin için harika çünkü eski ASCII dosyalarının hiç bir şekilde dönüştürülmesine gerek yok, ancak Avrupa dilleri için daha az kullanışlıdır ve Asya dilleri için çok az kullanışlıdır.

Yani temel olarak, evet, tek bir evrensel kodlamayı ve tek bir evrensel karakter grafiğini tanımlayabilirdik, ancak piyasa bunu kabul etmedi.


8
+1 Harika cevap. Dürüst olmak gerekirse, bu soruyu gerçekten cevaplayan tek kişi bu. Diğer tüm cevaplar, baytların tüm farklı unicode kodlamalarda nasıl yerleştirildiğiyle (az çok) ilgilidir.
Jacek Prucia

Tarihsel olarak basit bir anlaşmazlık sorunu. Ancak bugün UTF-8 dışında hiçbir şey için fazla kullanım görmüyorum, UTF-16'nın daha az yer kaplayacağı teorik senaryolar varken, büyük bir farkla değil, nadirdir. Yer kazanmak istediğiniz en belirgin yer web siteleri içindir, ancak UTF-8 kullanarak çok kısa süren HTML kodlarıyla doludur. Örneğin Shift JIS, bir Japon web sitesini UTF-8 eşdeğerinden daha küçük yapmak için kullanabilirsiniz , ancak bu yalnızca Japonca için özel bir karakter olduğu için işe yarar .
aaaaaaaaaaaa

2
Gerçekten de doğru değil. Sıkıştırılmış formatlar gerçekten sadece taşıma ve depolama için kullanılır. Bir uygulamada, UCS-2 veya UCS-4'ü kullanmak, genellikle sabit genişliklerdir, ancak bunlar karakter başına 2 veya 4 bayt alır. Dolayısıyla uygulamalar kullanım kolaylığı için alan bırakmaya isteklidir.
Martin York

but it is less useful for European languages, and of little use for Asian languages- bu sadece yanlış. "Yararlılık" derken sıkıştırma mı demek istiyorsun? Öyleyse UTF-8 avrupa dilleri için daha iyi sıkıştırma sağlar, çünkü her metinde sadece bir bayt alan boşluklar ve noktalama işaretleri bulunur.
Nick Volynkin

37

Unicode, benzersiz şekilde "Kod Noktaları" nı kodlayan 21 bitlik bir karakterdir ve her kod noktası bir glifle (grafiksel bir gösterimle) temsil edilir.

  • Bir düzlemdeki bir kod noktasını tanımlamak için kullanılan 16 bit (çoğu kod noktası 0 düzlemindedir).
  • Düzlemi tanımlamak için 5 bit.

Desteklenen kodlamalar:

  • UTF-8 (her noktayı 8 bit değer kullanarak kodlamak için)
  • UTF-16 (16 bitlik değerleri kullanarak her noktayı kodlamak için)
  • UTF-32 (her noktayı 32 bit değer kullanarak kodlamak için)

Ancak kod çözme işleminde kodlamanın ne olduğu önemli değildir, aynı anlamı taşıyan belirli bir kod noktasına geri eşlenirler (bu yüzden havalıdır).

UTF-8

Bu değişken boyutlu bir formattır. Her bir kod noktasının 1 ila 4 bayt ile temsil edildiği yer

UTF-16

Bu değişken boyutlu bir formattır. "Çok Dilli Düzlem" (BMP veya Düzlem 0) 'daki kod noktaları 1 adet 16 bitlik değer ile gösterilebilir. Diğer düzlemlerdeki kod noktaları, bir vekil çifti ile gösterilir (2 16 bit değer).

UTF-32

Bu sabit boyutlu bir formattır. Tüm kod noktaları tek bir 32 bitlik değer ile temsil edilir.


2
Ben de bu cevabı seviyorum. Benzer bir yazı yazıyordu ama bu açık. Ayrıca UTF-8'in ASCII dizelerinin otomatik olarak UTF-8 olması için de faydalı olduğunu eklerdim.
Kevin Hsu

4
Lütfen, temel dilli düzlem , düz değil .
JSB

3
Bu iyi bir cevap, ancak bence hala "Neden?" Sorusunu soruyor. Detaylandırmak için: UTF-32, Unicode karakterleri kodlamak için daha doğrudan (bazıları kolay diyebilir) bir yaklaşımdır, ancak her karakter 4 byte harcadığı için çok fazla alan harcar. UTF-8, ASCII ile çok daha kompakt ve geriye uyumludur, ancak normal değildir: karakter kodlamanın 1 ila 4 bayt alabildiği bir yerde çalışmasını zorlaştırır. UTF-16, ikisi arasında, çoğunlukla her birinin lehte ve aleyhinde olan bir tür karma yaklaşımdır.
mipadi

4
Bellek kullanımı (UTF-8 en iyisidir, çünkü en yaygın karakterler tek bayt olduğu için) ve işlem hızı (UTF-32'nin en iyisi olduğu yerler arasındadır), çünkü tüm karakterler aynı boyuttadır, belirli optimizasyonlara izin verir ve mükemmel verir. Bellekte 32 bit hizalama). Sonuç olarak, ağ protokolleri ve dosya formatları genellikle UTF-8'i kullanır (bant genişliğini / depolama alanını korumak için), komut dosyası tercümanları ve dil çalışma zamanları UTF-16 veya UTF-32'yi tercih edebilir.
tdammers

2
@Marcel: Bir "CodePoint" bir "CodePoint" değil character, bir karakterdir (bir karakter birden fazla "CodePoints" den oluşturulabilir). İki terimin kafasını karıştırmayın. Fakat haklısın "CodePoints" glifleri ifade etmiyor. Glif, bir kod noktasının grafiksel bir gösterimidir. İnce fakat önemli bir fark.
Martin York

25

2 fikri ayırmanın faydalı olduğunu düşünüyorum:

  1. Unicode - dünyanın her yerindeki karakterlerin kod noktalarına eşlenmesi.
  2. Kodlama - kodun bit desenlerine eşlenmesi (UTF-8, UTF-16, vb.)

UTF-8, UTF-16 ve diğer kodlamaların her birinin kendine göre avantaj ve dezavantajları vardır. Daha iyi bu konuda Wikipedia'ya danışın .


jfs: Yine de hala tel üzerinde farklı olan bir düzine veya daha fazla farklı kodlama olacaksa, Unicode neden olmasın? Küresel bir haritalamanın kendi başına ne yararı var?
Matthew Scharley

10
@ Matt Scharley: Yanlış bakıyorsun. UNICODE, tüm dillerdeki (Klingon dahil) tüm karakterleri UNIQUE ID'ye (kod noktası) eşler . Kodlamalar yalnızca kod noktaları diske veya ağdaki bir akıma sıkıştırmanın bir yoludur. UTF "UNICODE Transport formatı" anlamına gelmektedir. Her zaman bir UNICODE kod noktasını 21 bitlik bir değer olarak düşünmelisiniz. Diğer formatlara göre avantaj, tüm karakterlerin benzersiz bir şekilde tanımlanması ve örtüşmemesidir (Latin-1, Latin-2 vb. Gibi).
Martin York

@Matthew Scharley Neden küresel bir haritalamaya sahipsiniz? Aslında geçmişte herkes kendi haritasına sahipti (kod sayfalarını hatırladın mı?). Aptal bir örnek olayları temizleyeceğini düşünüyorum. Aşk fikrini hayal edin. Bunu birisiyle nasıl temsil edeceksin? Çiçek ver? Seni seviyorum de"? Herkesin kendi ifade etme yolu vardır. Aşk (soyut bir fikirdir) kod noktaları gibidir. İfade etmek kodlamalar gibidir. :)
jfs

4
Unicode küresel alfabedir. UTF-x, bilgisayarlar arasında taşındığı yoldur;
Mel

1
@ Martin, Klingon aslında başaramadı. Ayrıca Tengwar veya Cirith, Tolkein'in on bir dilini yazmak için de kullanılmadı.
TRiG

9

UTF-7, UTF-8, UTF-16 ve UTF-32, aynı kodlama karakterlerinin (kod noktaları) algoritmik dönüşüm biçimleridir . Bunlar kodlamaları karakter kodlama biri sistemin.

Ayrıca 256 karakterden daha büyük karakter kümeleriyle başa çıkmak için önceki planlardan daha ileri ve geri gitmek için algoritmik olarak daha kolaydır.

Bu, genel olarak ülkeye ve bazen de üreticiye özgü glif kodlama işlemlerinden çok farklıdır. Sadece Japonca'da, EUC-JP ve JIS'in kod sayfası yönelimli dönüşümünden bahsetmek yerine, Shift-JIS olarak adlandırılan DOS / Windows makinelerinin kullandığı bir ton JIS varyasyonu vardı. (Bir dereceye kadar, bunların algoritmik dönüşümleri vardı, ancak bunlar çok basit değildi ve mevcut karakterlerde satıcıya özgü farklılıklar vardı. Bunu birkaç yüz ülke ve daha sofistike font sistemlerinin kademeli evrimi ile çarpın (yeşil ekran sonrası) ()) ve sen gerçek bir kabus gördün.

Unicode'un bu dönüşüm biçimlerine neden ihtiyacınız var? Birçok eski sistem ASCII-aralığı 7 bitlik karakter dizilerini kabul ettiğinden, bu sistemler arasında bozulmamış verileri güvenli bir şekilde ileten 7 bitlik bir temiz çözüme ihtiyacınız vardı, bu yüzden UTF-7'ye ihtiyacınız vardı. O zaman 8 bitlik karakter setleriyle başa çıkabilecek daha modern sistemler vardı, ama nullların genellikle kendileri için özel anlamları vardı, bu yüzden UTF-16 onlar için işe yaramadı. 2 bayt, ilk enkarnasyonunda bütün çok dilli Unicode düzlemini kodlayabiliyordu, bu yüzden UCS-2, "Unicode yukarıdan haberdar" (Windows NT ve Java VM gibi) olacak sistemler için makul bir yaklaşım gibi görünüyordu; sonra bunun ötesindeki uzantılar ek karakterler gerektiriyordu, Unicode standardı tarafından ayrılan 21 bitlik kodlama değerinde algoritmik dönüşümle sonuçlandı ve taşıyıcı çiftler doğdu; Bu UTF-16'yı gerektiriyordu. Karakter genişliğinin tutarlılığının depolama verimliliğinden daha önemli olduğu bir uygulamanız varsa, UTF-32 (bir zamanlar UCS-4 olarak adlandırılır) bir seçenekti.

UTF-16, başa çıkmak için uzaktan karmaşık olan tek şeydir ve bu dönüşümden etkilenen küçük karakter dizileri ve 16 bitlik dizilerin net bir şekilde izinden tamamen farklı bir aralıkta olması gerçeği ile hafifletilir. 16 bit dizileri. Ayrıca, kaçış dizileriyle başa çıkmak için bir devlet makinesine (JIS ve EUC) ihtiyaç duyduğunuz ya da kaçınılmaz dizileriyle başa çıkmak için potansiyel olarak birkaç karakter geri hareket ettirdiğiniz, Doğu Asya'daki birçok kodlamada ileri ve geri gitmeye çalışmaktan daha kolay. sadece bir öncü bayt (Shift-JIS) olabilir. UTF-16, 16 bit dizilerde de etkili bir şekilde dolaşabilecek sistemler üzerinde bazı avantajlara sahipti.

Orada onlarca (yüzlerce, gerçekten) farklı kodlama yapmak zorunda kalmadınız ya da bazen aynı belgede (eski MacO sürümlerinde WorldScript gibi) bile farklı kodlamalarda birden fazla dili destekleyen sistemler kurmak zorunda kalmıyorsanız, düşünebilirsiniz. Unicode dönüşüm biçimlerinin gereksiz karmaşıklık olarak. Ancak, önceki alternatiflere göre karmaşıklıkta çarpıcı bir azalma var ve her format gerçek bir teknik kısıtlamayı çözüyor. Bunlar ayrıca, karmaşık bir arama tabloları gerektirmeden, aralarında gerçekten verimli bir şekilde dönüştürülebilir.


1
Çeşitli JIS ve EUC devlet makineleri gerçekten kötüdür ve iki kat arasında, eğer bunlar arasında dönüşümle çalışıyorsanız. Unicode bunu çok basitleştirir. Unicode ile sadece büyük sorun olmanızdır var karakter olarak bayt durdurma düşünmeye, sen ASCII kullanarak şovenist sizi küçük karakter-setted!
Donal Fellows

6

Unicode, birçok farklı kodlamaya sahip olma konusunu ele almak için tasarlanmamıştır.

Unicode, kullanılan kod sayfasına bağlı olarak birçok farklı şeyi temsil eden bir sayının tümünün etrafından dolaşmak için tasarlanmıştır. 0 - 127 arasındaki numaralar, herhangi bir Ansi kod sayfasındaki aynı karakterleri temsil eder. ASCII şeması veya karakter kümesi olarak da bilinir. 256 karaktere izin veren Ansi kod sayfalarında, 128 - 255 arasındaki sayılar, farklı kod sayfalarındaki farklı karakterleri temsil eder.

Örneğin

  • 57 $, tüm kod sayfalarında büyük W harfidir, ancak
  • $ EC, kod sayfası 437'deki (ABD) belirsizlik sembolünü gösterir, ancak kod sayfası 775'teki (Baltık) "LATİN KÜÇÜK HARF NEDİR
  • Cent İşareti, kod sayfası 437’de 9B’dir;

Unicode'un yaptığı her şeyi tersine çevirmekti. Unicode'da "yeniden kullanım" yoktur. Her sayı tek bir benzersiz karakter gösterir. Unicode'daki $ 00A2 sayısı yüzde işaretidir ve yüzde işareti Unicode tanımında başka hiçbir yerde görünmez.

Öyleyse neden bu kadar çok Unicode kodlaması var? UTF-8, UTF-16, vs. gibi (esasen) aynı olanın birden fazla versiyonu bile

Aynı kodlamanın birden fazla sürümü yok. Aynı Unicode karakter tanımı haritasının çoklu kodlamaları vardır ve bunlar Unicode'da bulunan çeşitli dilsel düzlemlerin farklı kullanımları için depolama gereksinimlerini yönetmek üzere "icat edilmiştir".

Unicode, 4.294.967.295 benzersiz karakterleri tanımlar (veya tanımlayacak alana sahiptir). Bunları herhangi bir algoritmik dönüşüm yapmadan disk / bellek deposuyla eşlemek istiyorsanız, karakter başına 4 bayta ihtiyacınız vardır. Tüm dil düzlemlerinden karakterleri içeren metinleri saklamanız gerekiyorsa, UTF-32 (temel olarak düz 1 karakter - unicode tanımının 4 bayt depolama kodlamasıdır) muhtemelen ihtiyacınız olan şeydir.

Ancak neredeyse hiç bir metin tüm dilsel düzlemlerden karakter kullanmaz. Ve sonra karakter başına 4 bayt kullanmak büyük bir atık gibi görünüyor. Özellikle dünyadaki birçok dilin Temel Çok Dilli Düzlem (BMP) olarak bilinen dilde tanımlandığını göz önüne aldığınızda: Unicode tanımının ilk 65536 sayısı.

UTF-16'nın girdiği yer de burasıdır. BMP'den yalnızca karakter kullanıyorsanız, UTF-16 karakter başına yalnızca iki bayt kullanarak bunu verimli bir şekilde kaydeder. BMP dışındaki karakterler için yalnızca daha fazla bayt kullanır. UTF-16LE (Little Endian) ve UTF-16BE (Big Endian) arasındaki fark, yalnızca sayıların bilgisayar belleğinde nasıl temsil edildiğiyle ilgilidir ( A0onaltılık hex = A0 veya $ 0A anlamına gelir).

Metniniz, Batı Avrupa dillerindeki çoğu metin gibi, daha az farklı karakter kullanıyorsa, metinleriniz için depolama gereksinimlerini daha da kısıtlamak isteyeceksiniz. Bu nedenle, ASCII şemasında bulunan karakterleri (ilk 128 sayı) ve Ansi karakterlerinden (çeşitli kod sayfalarının ikinci 128 sayısı) bir seçimde bulunan karakterleri depolamak için tek bir bayt kullanan UTF-8. Bu "en çok kullanılan karakter" kümesinin dışındaki karakterler için yalnızca daha fazla bayt kullanır.

Yani özetlemek için:

  • Unicode, dünyadaki tüm dillerdeki (ve önyüklenecek bazı Klingon) karakterlerin ve daha sonra bazılarının (matematiksel, müzikal vb.) Benzersiz bir sayıya eşlenmesidir.
  • Kodlamalar, metinlerin içindeki karakterlerin "ortalama kullanımı" göz önüne alındığında, bu benzersiz karakter haritasının sayılarını mümkün olduğu kadar verimli bir şekilde kullanarak metinleri depolamak için tanımlanmış algoritmalardır.

2
"0 - 127 arasındaki numaralar, herhangi bir kod sayfasındaki aynı karakterleri temsil eder." - peki, eğer $57
EBCDIC’ten

@ MSalters: kesinlikle haklısın. EBCDIC farklıdır (ve diğerleri de EBCDIC vardır). Sanırım anabilgisayar günlerimin arkamda o kadar uzun ki hatırlamıyorum ya da bu hatıraları çok sert ve çok bastırdım ... :-)
Marjan Venema

"0 - 127 arasındaki numaralar, herhangi bir kod sayfasındaki aynı karakterleri temsil eder." Aslında ASCII'nin süperseti olmayan BinarySignWriting gibi kodlamalar var. BinarySignWriting, aslında, hiçbir ASCII karakteri içermez.
TRiG

@ TRiG: Bu yüzden bildiriyi özellikle Ansi kod sayfalarıyla ilgili olarak düzenledim. Yenilenmeden önce yapmış olmalı ...
Marjan Venema

Evet. Yorumumu yazarken fazladan bir yorum yapıldı ve mesaj güncellemesi yapıldı. Yine de, BinarySignWriting ilginçtir.
TRiG

2

Unicode haritayı sayılar ve karakterler arasında tanımlar. Ancak, bir alıcıya bir numara gönderdiğinizde, hala bu numarayı nasıl temsil edeceğinizi tanımlamanız gerekir. UTF bunun için var. Bayt akışında bir sayının nasıl temsil edileceğini tanımlar.


2

UTF-32'nin ardındaki mantık basit: Unicode kod noktalarının en basit gösterimi. Peki neden UTF-32’de her şey yok? İki ana sebep:

Birincisi boyuttur . UTF-32 her karakter için 4 bayt gerektirir. Çok Dilli Temel Yerinde yalnızca karakter kullanan metin için bu, UTF-16'nın iki katı kadardır. İngilizce metin için, US-ASCII'den 4 kat daha fazla alan var.

En büyük neden geriye dönük uyumluluktur . "Kodlanmamış" UTF-32 dışında kodlayan her Unicode, önceki standartlarla geriye dönük uyumluluk için tasarlanmıştır.

  • UTF-8: US-ASCII ile geriye dönük uyumluluk.
  • UTF-16: UCS-2 ile geriye dönük uyumluluk (BMP'nin ötesine genişletilmeden önce 16-bit Unicode).
  • UTF-7: 8 bit olmayan temiz posta sunucularıyla geriye dönük uyumluluk.
  • GB18030: Çince için GB2312 ve GBK kodlamaları ile geriye dönük uyumluluk.
  • UTF-EBCDIC: EBCDIC'in Temel Latin alt kümesiyle geriye dönük uyumluluk.

Unicode'un birçok farklı kodlamaya sahip olmanın tüm sorununu çözecek şekilde tasarlandığını düşündüm.

Öyleydi ve yaptı. UTF-8, -16 ve -32 arasında dönüştürme yapmak, farklı diller ve farklı işletim sistemleri için kullanılan yüzlerce farklı karakter kodlamasının eski sistemiyle uğraşmaktan çok daha kolaydır .


1

Bir zip dosyasının bir dosyayı çok daha küçük (özellikle metin) olacak şekilde sıkıştırabileceğini ve ardından orijinal dosyanın özdeş bir kopyasını açabileceğini biliyorsunuz.

Sıkıştırma algoritması aslında seçilebilecek farklı özelliklere sahip birkaç farklı algoritmaya sahiptir: kaydedilmiş (sıkıştırma yok), Küçültülmüş, İndirgenmiş (1-4 yöntemleri), Uygulama, Tokenizasyon, Sönük, Deflate64, BZIP2, LZMA (EFS), WavPack, PPMd, teorik olarak hepsini deneyebileceği ve en iyi sonucu seçebileceği yer ancak genellikle Sönük ile gitmek.

UTF de aynı şekilde çalışır. Her biri farklı özelliklere sahip çeşitli kodlama algoritmaları vardır, ancak genellikle UTF-8'i seçersiniz, çünkü sırayla 7-bit ASCII'ye bit bit uyumlu olması nedeniyle 7FT ASCII'ye göre birebir uyumludur. genellikle 8 bitlik bir ASCII uzantısı kullanan çoğu modern bilgisayar platformunda kullanın.


ørn: Bir zip dosyasıyla olan fark, hangi sıkıştırma işleminin etkin olduğunu söyleyen bir başlığın olmasıdır. Metin dosyaları ile hala tahmin etmemiz gerek, değil mi?
Matthew Scharley

Tam olarak bunu söyleyen özel bir dizi var. ASCII ile geriye dönük uyumluluk nedeniyle isteğe bağlıdır.
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.