Karakter kodlaması

Bilişimde karakter kodlaması kavramı bir çeşit kodlama sistemi kullanılarak kodlanmış karakter gruplarını temsil etmektedir. Soyutlama düzeyi ve kullanıldığı bağlama bağlı olarak karakterlere karşılık gelen kod noktaları ve bunların oluşturdukları kod alanı, bit örüntüleri, oktetler, doğal sayılar, elektrik sinyalleri vb. şeklinde algılanabilir. Metinsel verilerin işlenmesi, depolanması ve iletimi esnasında karakter kodlamaları kullanılır. Karakter seti, karakter eşlem veya kod sayfası gibi ifadeler karakter kodlaması kavramıyla eş anlamlıymış gibi kullanılsa da aralarında bazı anlam farkları bulunmaktadır.
Optik ve elektronik telgrafla ilişkili eski karakter kodları yazılı dilde kullanılan karakterlerin, büyük harfler, rakamlar ve bazı noktalama işaretleri gibi yalnızca belli bir kısmını temsil edebiliyordu. Çağdaş bilgisayar sistemlerinde verilerin sayısal olarak temsil edilmesinin oldukça düşük maliyetli olması sayesinde karakter temsili çok daha ayrıntılı olabilmektedir (Unicode'da olduğu gibi). Günümüzde, dünyadaki birçok yazı dilinde kullanılan eskisinden çok daha fazla karakter, karakter kodlamaları aracılığıyla dijital ortamda temsil edilebilmektedir. Karakterler kodlanırken önceden belirlenmiş uluslararası standartlara uyulması metinlerin tüm dünyada elektronik olarak takas edilmesine olanak tanımaktadır.

Unicode kodlama modeli

Unicode ve paralel standardı ISO/IEC 10646 Evrensel Karakter Kümesi modern, birleştirilmiş bir karakter kodlama sisteminin oluşmasını sağlamıştır. Karakterleri doğrudan sekizli bit değerleri olarak (baytlar halinde) kodlamak yerine, bu süreci ayrı aşamalara bölmüştür. Bu standartla hangi karakterlerin kodlama standardına dahil edileceğinin belirlenmesi (karakter dağarcığının belirlenmesi), bu karakterlerin her birine birer numara verilmesi (kodlu karakter kümesinin oluşturulması), karakterlere verilen numaralar için kodlama biçimlerinin belirlenmesi ve en sonunda da karakterlerin belirlenen yöntemlerden birine göre birler ve sıfırlar halinde kodlanması işlemleri birbirinden ayrılmıştır. Birinci aşama diğer tüm aşamaların ortak zeminini oluşturmaktadır . Böylece farklı kodlama türlerinin temel alacağı ortak bir karakter kümesi oluşturulmak istenmiştir. ASCII ve genişletilmiş ASCII sistemlerinde bu aşamaların hepsi tek parça halindeydi. Dolayısıyla kodlama sistemleri arasında uyumsuzluk söz konusuydu. Her bir genişletilmiş ASCII setinde farklı bir karakter kümesi bulunuyordu. Unicode kodlama sistemlerinin ise tamamı aynı ortak karakter dağarcığını esas alır.
Bu modelin nasıl işlediğini anlatabilmek için "karakter kümesi" ve "karakter kodlaması" gibi belirsiz terimler yeterli olmamaktadır. Bu modeli açıklarken kullanılan terimler şunlardır:

Karakter dağarcığı

Karakter dağarcığı bir sistemin desteklediği soyut karakterlerin tamamından oluşan gruba verilen addır. Bu dağarcık kapalı ya da açık olabilir. Kapalı olması durumunda dağarcığa yeni bir karakter eklenebilmesi için yeni bir standart oluşturulmalıdır (örneğin ASCII standardına yeni karakterler eklenebilmesi için Genişletilmiş ASCII adıyla yeni bir standart oluşturulması gerekti; çünkü ASCII kapalı bir karakter dağarcığından oluşuyordu). Açık olması durumunda eklemelerin yapılması mümkün olmaktadır (örneğin Unicode sistemi tamamen ve Unicode öncesinde Windows işletim sisteminde kullanılan kodlama standardı olan Windows kod sayfaları kısmen açıktır). Karakter dağarcıkları, yazı sistemlerinin en temel bileşenlerine nasıl ayrılabileceği üzerinde düşünülerek oluşturulur. Latin alfabesi ve türevleri, Yunan alfabesi ve Kiril alfabesi, değişik sıralamalarla art arda dizildiklerinde okunabilen metinler oluşturabilecek temel harflere, noktalama işaretlerine, sayılara ve boşluk karakteri gibi bazı özel karakterlere ayrılabilir. Birimlerine ayrılması kolay gibi görünen bu alfabelerde bile aksan işaretleri gibi bazı önemli sorunlar ortaya çıkmaktadır: aksanlı karakterler başlı başına ayrı birer karakter olarak da düşünülebilirler, aksansız harf ve aksan işaretinin bir araya gelerek oluşturduğu karakter grubu olarak da düşünülebilirler. Birinci durum metinlerin işlenmesini kolaylaştıracaktır ancak ikinci durum tüm aksan ve harf kombinasyonlarını olanaklı kılmak için kullanışlı bir yol sağlayacaktır. Ayrıca bazı Batı dillerinde yan yana gelen bazı harflerin görsel zenginlik sağlamak amacıyla birleştirilmesi olan tipografik bağların (ligatür) yazımı da benzer şekilde sorun oluşturmaktadır. Arapça ve İbranice gibi başka yazı sistemlerinin sağdan sola yazılıyor olması ve ayrıca Arapçada aynı harfin tek başınayken, kelimenin başındayken, ortasındayken ve en sondayken farklı şekillerde yazılıyor olması çift yönlü metinlerin desteklenmesi ve gliflerin farklı koşullarda farklı şekillerde yazılmasının olanaklı hale getirilmesi açısından sorun oluşturmaktadır.

Kodlu karakter kümesi

Kodlu karakter kümesi (İngilizce kısaltmasıyla CCS) karakter dağarcıklarının kod noktası adı verilen (genellikle negatif olmayan) tam sayılar kullanılarak nasıl temsil edileceğini belirtir. Örneğin Latin harflerini de içeren karakter dağarcığında "A" harfi 65 sayısıyla sıradaki diğer harfler de 66, 67 şeklinde devam eden sayılarla eşleştirilebilir. Dolayısıyla böyle bir sistemde "A" harfinin kod noktası 65'tir denir. Karakterlere atanan bu sayılar, yazı birimlerinin dijital ortamda temsil edilmesinin ilk aşaması olarak düşünülebilir. Daha sonraki aşamada kod noktalarının hangi yöntemle 1'lere ve 0'lara dönüştürüleceği ve bu esnada hangi uzunlukta kod birimlerinin kullanılacığına karar verilecektir. Karakter dağarcığındaki tüm karakterler ve onlara karşılık gelen sayıların birlikte oluşturduğu gruba kodlu karakter kümesi denir. Çeşitli kodlanmış karakter kümeleri aynı dağarcığı paylaşabilirler, örneğin ISO/IEC 8859-1 ve IBM 037 ve 500 numaraları kod sayfaları aynı dağarcığı paylaşmaktadır ama bu karakterleri farklı sayılarla eşleştirmişlerdir. kodlu karakter kümesinde, her kod noktası sadece bir karakteri temsil eder, yani kodlu karakter kümesi bir fonksiyondur.

Karakter kodlama biçimi

Karakter kodlama biçimi (İngilizce kısaltmasıyla CEF), kodlu karakter kümesinde bulunan kod noktalarının, sayıları belirli uzunluktaki bitlerle ikili biçimde temsil eden bir sistem üzerinde (yani tüm bilgisayar sistemlerinde) depolanabilecek bir şekilde iki tabanında ifade edilen kod değerlerine nasıl dönüştürüleceğini belirleyen kurallar bütünüdür.
Bilgisayar sistemleri, ikil verileri tek tek bitler halinde kullanmaz. Verinin işlenmesi ve alınıp verilmesini kolaylaştırabilmek için verileri belirli uzunluktaki kalıplar halinde ifade ederler. Bu yüzden, kod noktaları da bitlerle ifade edilirken, bir veya daha çok sabit uzunluklu kod birimiyle ifade edilmelidir. Bu kod birimlerinin uzunluğu belirlenirken, kullanılan bilgisayar sisteminin teknik özelliklerini göz önünde bulundurmak gereklidir. Bunlar bayt uzunluğu ve sözcük uzunluğudur. Bellekte adreslenebilen en küçük veri parçası bayt olarak adlandırılır. Baytlar genellikle 8-bit uzunluğundadır. Sözcük ise işlemci tarafından tek seferde işlenebilen en büyük veri uzunluğudur ve genelde iki bayttır (16-bit). 8-bitlik baytlar kullanan bir sistemde veriler 8 bit ve katları halinde okunur, yazılır ve aktarılır.
Örneğin karakter kodlamasında kod biriminin 16-bit uzunluğunda seçildiğini düşünelim. Böyle bir sistemde 0 ile 65.535 arasındaki sayılar (yani Unicode Temel Çokdilli Düzleminde bulunan kod noktası sayısı) tek bir 16-bitlik birim ile yazılabilirken daha büyük sayılar için birden fazla birim kullanılması gerekecektir. Tek bir kod birimi de tam olarak iki baytla (8-bitlik) ifade edilebilir. 32-bitlik birimler kullanıldığında ise tüm kod noktaları birer birimle ifade edilebilir. Ancak bu durumda verinin kapladığı yer çok artacak ve dolayısıyla taşınması zorlaşacaktır. İşte karakter kodlama biçimlerinin uygun bir şekilde yönetmesi gereken durum budur: sınırlı bir aralıkta bulunan  (örneğin 0 ile 1.4 milyon arası) tek bir kod noktasını, her biri daha sınırlı bir aralıktaki sayıları temsil edebilen bir ya da daha fazla kod biriminden (örneğin her biri 0 ile 65.525 arası sayıları temsil edebilen 16-bitlik kod birimlerinden) oluşan kod değerlerine dönüştürmek için bir yöntem belirler. Bu yöntemi belirlerken, verinin işlenme kolaylığı ve kaplayacağı yeri göz önünde bulundurmaları gerekir.
En basit karakter kodlama biçimi, her bir kod noktasının tek bir kod birimiyle ifade edilebileceği şekilde büyük kod birimleri seçilerek yapılan bir kodlama olacaktır (bir kod noktasının bir kod biriminden oluşan bir kod değerine karşılık geldiği). Bu yöntem, 8 bitlik birimlere sığabilen kodlanmış karakter kümeleri için (örneğin eskiden kalan genişletilmiş ASCII kodlamalarının çoğu gibi) gayet iyi ve 16 bitlik birimlere sığabilenler için de (örneğin Unicode'un eski sürümleri, görece daha az sayıda karakter içerdiği için) az çok iyi işlemektedir. Ancak kodlu karakter kümesinin boyutu büyüdükçe bu yöntem giderek verimsizleşmektedir. Örneğin Unicode'un günümüzdeki sürümündeki her karakteri bu yöntemle kodlamak için 21 bit uzunluğunda kod birimleri kullanmak gerekecektir. Hatta çoğu sistem verileri 8-bit ve katları şeklinde temsil ettiğinden kod birimi en az 24-bit uzunluğunda olacaktır. Böyle bir sistem veri boyutu sorunun yanı sıra eski sistemlerde uygulanması da zor bir sistem olduğundan kullanışsızdır. Bu yüzden daha küçük kod birimleri kullanan çeşitli kodlama biçimleri tasarlanmıştır. Unicode'un ileriki sürümleriyle çalışan sistemler ya UTF-8 ya da UTF-16 kodlama biçimlerini kullanmaktadır. UTF-8, kod noktalarını bir veya daha fazla sayıda 8-bitlik kod birimleriyle ve UTF-16 da iki adet 16-bitlik kod birimiyle ifade eder.
Karakter kodlama biçimleri daha önce de belirtildiği gibi her karakteri tek bir kod birimiyle kodlarsa, bu şekilde kodlanmış bir karakter dizisinde art arda gelen karakterlerin nerede başlayıp nerede bittiği belirli olacaktır (her karakter sabit uzunluktaki bir bit dizisiyle ifade edildiğinden). Ancak, UTF-8 ve UTF-16 gibi karakterlerin bir veya fazla kod biriminden oluşabildiği kodlamalarla kodlanmış karakter dizileri yazılımlar tarafından işlenirken, bir karakterin nerede bitip diğerinin nerede başladığının anlaşılabilmesi önemli bir sorun olarak ortaya çıkmıştır. Farklı kodlama biçimleri farklı yöntemler kullanarak bu sorunun üstesinden gelmişlerdir. Örneğin kısaca söylemek gerekirse UTF-8 kodlaması bu sorunu, kodlama esnasında kod birimlerinin başına o kod biriminin yeni bir karakterin başlangıcı mı yoksa bir önceki kod biriminin kodladığı karakterin devamı mı olduğunu belirten bir takım işaretçi bitler koyarak çözmüştür.