UTF - 8 Mucizesi

Bu yazımda bilgisayar dünyasına büyük bir kolaylık sağlayan, bilgisayarlar için küçük ama insanlık için büyük olan UTF-8'den bahsedeceğim.
UTF — 8; Ken Thompson ve Rob Pike tarafından geliştirilen, tanım olarak Unicode dönüşümünden türetilen, elektronik iletişim için kullanılan değişken uzunluklu bir karakter kodlama standardıdır. Kısaca UTF-8, Unicode için bir kodlama sistemidir.
Peki bu tanımdan ne anlamalıyız? Doğrudan UTF-8'e değinmeden önce Binary, ASCII ve Unicode’dan bahsedeceğim.
Gündelik hayatımızda bizler onluk sayı sistemi ile çalışmaktayız. Bilgisayarlar ise ikilik yani binary sayı sistemiyle çalışırlar. Bilgisayarlar için sadece 1 (true) ve 0 (false) vardır. Bilgisayarların bu bahsedilen 1–0'ları ise transistör üzerinden geçen elektrik akımı sayesinde anlamaktadır. Yani transistör üzerinden akım var ise 1, yok ise 0'dır.
Eğer var-yok durumunu değil, harf veya sayı tutmak istersek de 8 tane bit (binary digit) ile yani 1 byte ile elde edebiliyoruz. 8 bit ile de 256 olasılığı tutabilmekteyiz.
Karakterlerin de hangi binary’e denk geldiğini bir standarda dökmek amacıyla da ASCII (American Standard Code for Information Interchange, en; Bilgi Değişimi İçin Amerikan Standart Kodlama Sistemi, tr) standardı oluşturuldu. İngiliz alfabesinde bulunan 26 tane harfin küçük ve büyük durumları ve kullanılan sembolleri bu standarda eklediler.

Bu tabloda klavye üzerinde bulunan tüm karakterlere bir decimal karşılık atadılar ve bu decimal karşılığı ikilik tabana çevirerek bilgisayara anlatmayı hedeflediler. Tüm karakterler için 127 tane olasılık, yani 7 bit yeterlidir. Örneğin, ‘S’ karakteri için 83 > 01010011, s için ise 115 > 01110011 kullanılmakta.
sahibinden kelimesini binary olarak yazmak istersek de aşağıdaki gibi yazmalıyız.

Buraya kadar her şey çok güzel ilerliyor gibi duruyor. Peki İngiliz alfabesi kullanmayan ülkeler bu durumu nasıl çözecek? Örneğin SAHİBİNDEN yazmak istiyoruz fakat ‘İ’ karakteri için ASCII tablosunda bir karşılık bulunmamakta. Bu sorunu çözmek için ise Extended ASCII geliştirildi. ASCII tablosu 127 olasılık, yani 7 bit kullanmakta ve baştaki bit boşta. Bu boştaki bit’i kullanarak 256 olasılık elde etmiş oldular, farklı karakterlere sahip ülkeler için standartlar oluşturuldu.
Fakat bu çözüm de yeterli olmamaya başladı, emojileri ve farklı sembolleri tutmak için de Unicode geliştirildi. Unicode, dünyada kullanılan genel geçer yazı karakter ve sembollerini kodlayan bir standard. Unicode içerisinde herhangi bir dilde bulunan tüm karakterler, semboller ve emojilerin bir code point karşılığını oluşturdular. Örneğin, S harfinin code point karşılığı U+0053'dür. Unicode’a bakarak sadece bir karakterin hangi değere denk geldiğini anlayabilmekteyiz, binary karşılığını elde edemiyoruz. Bu problemin çözülmesi amacıyla da bir kodlama standardı ihtiyacı oluştu ve ortaya UTF-32, UTF-16 ve UTF-8 gibi (UTF: Unicode Transformation Format, en; Unicode Dönüşüm Formatı, tr) kodlama standardları çıktı.

Günümüz verileriyle Unicode 149.813 karakteri ve 161 alfabeyi tanımlayabiliyor. Bu da tüm karakterler için en az 32 bit’e ihtiyacımız olduğu anlamına geliyor. Unicode içerisinde ASCII tablosunda bulunan karakterlerin karşılığı yine aynı kaldı.
UTF-32: Tüm karakterleri 32 bit olarak kodlar.
UTF-16: İhtiyaca göre 32 bit ve 16 bit olarak kodlar.
Fakat bu kodlama standardlarıyla önceden ASCII tablosunda sadece 7 bit ile tüm karakterleri tutulabilen İngiliz alfabesi kullananlar fazladan 26 bit kullanmak durumunda kalmaya başladı ve her İngilizce metin dosyasının boyutu 4 kat fazla yer kaplamaya başladı.
Problem 1: İngiliz alfabesinde fazladan kullanılan bitler.
Problem 2: Eski bilgisayar sistemlerinde peş peşe gelen 8 adet 0 bitin NULL değer olarak okunması.
Problem 3: Unicode kullanarak sadece ASCII anlayan bir makinede çalıştırmak. (Geriye Uyumluluk — Backward Compatibility)
Bu problemlere çözüm olarak Ken Thompson ve Rob Pike UTF-8'i geliştirdiler.
Peki UTF-8'in olayı ne? Nasıl çalışıyor?
UTF-8 ilk olarak sadece ASCII’yi baz alarak başlıyor. 128'in altında bir değer sadece 7 bit ile ifade edilebilir. Eğer ilk bit 0 ise bunu ASCII tablosundan bir değer olarak algılar.
Tekrar ‘S’ karakteri için bakacak olursak; 01010011 şeklinde ifade edilir ve ilk bit 0 olduğu için UTF-8 bu binary değerin karşılığını ASCII tablosundan alarak ‘S’ olduğunu anlar.
Eğer gelen byte 110 ile başlarsa bunun yeni bir karakter başlangıcı olduğunu ve 2 byte uzunluğunda olacağını anlar. İkinci byte’ın devam niteliğinde olduğunun anlaşılması için ise 10 ile başlaması gerekir. Bu anlamı, çıkardığımız baştaki bitlerden sonra geriye kalan bitleri birleştirerek ortaya yeni bir binary sayı çıkarır ve hesaplamamızı yaparız.

Yani artık başta bahsettiğim büyük harflerle “SAHİBİNDEN” kelimesini aşağıdaki binary ile gösterebiliriz.

Eğer 1110 şeklinde başlarsa bu sefer de 3 byte uzunluğunda olacağını anlar ve yukarda şekillerle gösterdiğim işlemin aynısını 3 byte ile yapar. Bu şekilde 1111110x’e kadar gidebilir ve 6 byte uzunluğuna erişebiliriz.

Böylece:
- Fazladan bit kullanma zorunluluğu ortadan kalktı,
- Üst üste 8 tane 0 bit gönderme durumu ortadan kalktı,
- Geriye uyumluluk sağlandı.
Son olarak sadece ‘i’ karakterini içeren bir metin dosyası, sadece ‘İ’ karakteri içeren başka bir metin dosyası ve sadece 1 emoji içeren başka bir metin dosyası oluşturup kaç byte olduklarını görelim.



Sonuç olarak UTF-8, günümüzün çok dilli dijital dünyasında temel bir öneme sahiptir ve farklı karakter setlerini uyumlu bir şekilde bir araya getirerek iletişimi kolaylaştırır. Bu yazıyı, UTF-8'in önemini vurgulamak ve kullanımını anlatmak amacıyla hazırladım.