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.
Kod birimi
Kod birimi kodlama düzenlerinin karakterleri bit dizilerine dönüştürürken kullandığı en küçük birimin genişliğidir. Kodlanmış karakterler bir veya daha fazla sayıda kod biriminden oluşur.
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.
Karakter kodlama düzeni
Karakter kodlama düzenleri (İngilizce kısaltmasıyla CES) sabit uzunluktaki kod değerlerinin oktet dizilerine eşlenme işleminin kurallarını belirler. Günümüzde bilgisayar sistemleri verileri sekiz bitten oluşan baytlar halinde gruplandırarak kullandığı için kodlanmış bit dizilerini oktetlere (yani sekiz bitten oluşan baytlara) dönüştürme işlemi metinsel veriyi oktet tabanlı dosya sistemlerine kaydetmeye veya oktet tabanlı ağlar üzerinden aktarmaya elverişli hale getirmek açısından gerekli olmaktadır. UTF-8 kodlama biçimi zaten 8-bitten oluşan kod birimleri kullanıdığından UTF-8 ile kodlanmış metinler için ayrı bir karakter kodlama düzeni gerekmez. Ancak örneğin UTF-16 ve UTF-32 kodlama biçimleri sırasıyla 16 ve 32 bitten oluşan kod birimleri kullandığı için bunlar ile kodlanmış verinin oktetlere dönüştürülmesi gerekir. Bu dönüştürme sürecinde iki farklı yol mevcuttur: büyük basamaklı kısımların önce geldiği (big-endian) veya tam tersi (little-endian). Dolayısıyla bu Unicode kodlama biçimleri için kullanılan kodlama düzeni baytların basamak sırasının (endian) nasıl olacağını belirtmekten ibarettir. Ancak bunlardan başka olarak bileşik karakter kodlama düzenleri (ISO/IEC 2022 gibi) de bulunmaktadır ki bunlar basit kodlama düzenleri arasında geçiş yapabilmek için kaçış dizileri (escape sequence) kullanırlar. Ayrıca kod birimi başına düşen bayt sayısını en aza indirmeye çalışan sıkıştırma düzenleri de mevcuttur (SCSU, BOCU, ve Punycode gibi). Ayrıntılar için Unicode kodlamalarının karşılaştırmasına bakabilirsiniz.
Karakter kodlama biçimleriyle karakter kodlama düzenleri birbirleriyle karıştırılmamalıdır. Unicode teknik raporunda bu farklar şu şekilde açıklanmıştır:
Kodlama biçimi kod noktalarını bir veya daha fazla kod birimine dönüştürürken, kodlama düzeni bu kod birimi dizilerini bayt dizilerine dönüştürür. (Karakterleri doğrudan doğruya diziselleştirilmiş (serialized) baytlara dönüştürme işlemi ise karakter eşlem olarak adlandırılır)
Bir bayttan daha geniş kod birimi kullanan kodlama biçimleri bayt dizilerine dönüştürülürken kodlama düzenleri tarafından bayt basamak sırası göz önünde bulundurulmalıdır.
Son olarak, farklı bölgelerde farklı şekillerde kullanıldığı halde Unicode tarafından tek bir karakter altında birleştirilen farklı bölgesel biçimlerden birini seçmek için gerekli ek bilgiyi sağlayan bir bir üst düzey protokol kullanılabilir. XML dilindeki xml:lang özniteliği buna bir örnektir.
Unicode modeline göre karakter eşlem terimi, karakterleri doğrudan bayt dizilerine dönüştüren, yani CCS, CEF ve CES katmanlarının her birini içinde bulunduran eski sistemleri ifade etmek için kullanılır.