Unicode Nasıl Çalışır: Her Geliştiricinin Dizeler ve 🦄 Hakkında Bilmesi Gerekenler


Gevşek ekran görüntüsü - Belki koda ihtiyacınız var ama bende bolca kodum var #dadjokes

Unicode nedir?

Waaay 2003 yılında Joel Spolsky Unicode ve neden her geliştiricinin bunun ne olduğunu ve neden önemli olduğunu anlaması gerektiğini yazmıştı. Bu makaleyi okuduğumu hatırlıyorum (ve o zamandan beri çoğunu unuttum), ancak karakter kümelerinin ve Unicode'un ne kadar önemli olduğu beni gerçekten etkiledi. İki yıl önce Unicode hakkındaki bu blog yazısının ilk versiyonunu yayınladık. Şimdi eski dostumuz Unicode'u tekrar ziyaret etmenin ve günümüzün emoji dolu dünyasında neden önemli olduğunu görmenin zamanının geldiğini düşündük 🦄💩. Farkında olmayabilirsiniz, ancak WordPress ile çalışıyorsanız zaten Unicode ile çalışıyorsunuzdur! Şimdi bunun ne olduğunu ve geliştiriciler için neden önemli olduğunu görelim.

“Unicode nedir?” Sorusuna cevap vermek için. önce geçmişe bakmalıyız.

ASCII kodlaması

Unicode'a girmeden önce biraz tarih yazmamız gerekiyor (4 yıllık tarih diplomam sonunda kullanıma başlıyor 🎉). Unix'in icat edildiği günlerde, karakterler 8 bit (1 bayt) bellekle temsil ediliyordu. O günlerde bellek kullanımı çok önemliydi çünkü bilirsiniz, bilgisayarlarda çok az şey vardı. David C. Zentgraf'ın blogunda bunun nasıl çalıştığına dair harika bir örneği var:

 01100010 01101001 01110100 01110011 bits

Tüm bu 1'ler ve 0'lar ikilidir ve altındaki her karakteri temsil ederler. Ama ikili olarak yazmak zor bir iştir ve uh, bunu her zaman yapmak zorunda kalsaydınız berbat olurdu. ASCII buna yardımcı olmak için yaratılmıştır ve esasen karakterlere göre bir bayt arama tablosudur.

ASCII Tablosu

ASCII tablosunda 128 standart karakter bulunur (hem büyük hem de küçük harf az ve 0-9). Aslında sadece 95 alfanümerik karakter var, bu da İngilizce konuşuyorsanız kulağa hoş geliyor. Gerçekte, her karakter yalnızca 7 bit gerektirir, bu nedenle biraz fazla kalır! Bu, diğer karakterlerin yanı sıra C ve Æ gibi 128 daha süslü şeye sahip genişletilmiş ASCII tablosunun oluşturulmasına yol açtı. Ne yazık ki bu, dünyadaki dillerde kullanılan çok çeşitli karakterleri kapsamak için yeterli değil, bu yüzden insanlar kendi kodlamalarını yarattılar.

90'ların sonunda, takip edilmesi gereken en az 60 standartlaştırılmış (ve birkaçı daha az) genişletilmiş ASCII tablosu vardı. Muhtemelen hepsinin en azından ilk 128 karakteri paylaştığı için minnettar olmalıyız. Ama zorunlu olarak, ek 128 karakteri çok farklı kullanıyorlardı, o kadar farklıydı ki, yanlışlıkla yanlış tablonun seçilmesi bir metni okunamaz hale getirebilirdi. Mükemmel.

Karakter kodlamaları interneti kırdı

Pekala, şimdi Microsoft'un Windows-1252 ve Big5'i gibi karşılaşmış olabileceğiniz tüm o bajillion karakter kodlamalarında neyin nesi olduğunu biliyoruz – insanların kendi dillerini ve benzersiz karakter dizilerini temsil etmesi gerekiyordu. Ve bu, belgeler diğer bilgisayarlarla paylaşılmadığında çoğunlukla işe yaradı. Bilirsiniz, internetten önceki zamanlar.

genç Bill Gates

İnternet tüm bunları bozdu çünkü insanlar kendi yerel kodlamalarında kodlanmış belgeleri diğer insanlara göndermeye başladı. Bazen insanlar aynı kodlamayı kullanmıyorlardı ve e-posta konu satırı olarak buna benzer bir şey görüyorlardı:

 �����[ Ef����Oi OCµC���¢!!

İşleri daha da karmaşık hale getirmek için, bazı kodlamalar 8 yerine 16 bit kullanır. Bu, çok büyük arama tabloları oluşturur. ASCII'den çok daha büyük!

ASCII? Hangi ASCII?

Uzun bir süre 256 karakterlik tablo iyi çalıştı. Basit ve verimliydi. Gerçekten tek bir sorun vardı: Hangi ASCII?

İnternet üzerinden birbirimize bir şeyler gönderirken, alıcıya hangi ASCII kodlamasını kullandığımızı tahmin etme şansı vermek önemlidir. Yıllar boyunca, tüm bu kodlamaların e-posta, elektronik tablolar, belgeler ve web sayfalarıyla uyumlu bir şekilde çalışmasını sağlamak için çok fazla enerji harcandı.

internet sayfaları

Bugün basit bir web sayfasını ziyaret ettiğinizde, doğru karakterleri gördüğünüzden emin olmaya çalışan, nitelikli tahmin de dahil olmak üzere, kullanımda olan bir dizi farklı teknik vardır.

Bir geliştirici olarak fark edeceğiniz en bariz yer HTML belgesinin kendisidir. Tarayıcıya Batı Avrupa latin karakter kümesini kullandığınızı söylemek için HTML'nin <head> bölümüne bir <meta charset="ISO-8859-1"> etiketi ekleyebilirsiniz. Bu etiket eksikse, tarayıcı web sunucusundan gelen yanıt başlıklarına bakar ve Content-Type başlığında ek bir karakter kümesi bildirimi bulabilir. HTML belgesi, bir <meta http-equiv="content-type"> etiketi ekleyerek web sunucusu tarafından gönderilen İçerik Türünü de geçersiz kılabilir.

Ancak asıl eğlence, bu üç farklı yer, kullanılan karakter kümesi hakkında farklı şeyler söyleyene kadar veya beyan edilen karakter kümesinin belgenin geri kalanında gerçekte kullanımda olmadığı ortaya çıkınca başlamadı. Chrome ve Firefox'un eski sürümlerinin, kullanıcının kodlamayı manuel olarak değiştirmesine izin vermesinin bir nedeni vardı.

e-postalar

E-posta sisteminin uluslararası karakterleri desteklemenin arkasında kendi üzücü hikayesi vardı. Üzüntünün çoğu, temeldeki SMTP protokolünün hala aktarılan içeriğin 7 bit olmasını gerektirmesinden kaynaklanmaktadır. Bu küçük sorun genellikle, 8 bitlik karakterleri 7 bitlik bir protokol üzerinden aktarma tekniği olan alıntı yazdırılabilir kodlama kullanılarak çözülür, böylece genişletilmiş ASCII karakterleri bir e-postada gönderilebilir. Muhtemelen alıntılanan yazdırılabilir kodlamanın yanlış gittiğini görmüşsünüzdür:

Konu: R=C3=A4ksm=C3=B6rg=C3=A5s

Alıntılanan yazdırılabilir kodlama akıllıca bir çözüm olsa da, sorunun yalnızca bir kısmını çözer. Alıcı e-posta istemcisinin hala tüm olası ASCII tablolarından hangisini kullanacağını bulması gerekiyor.

Bugün gönderilen hemen hemen tüm e-postalar, gerçek e-posta içeriği için MIME standardını kullanır. MIME, temel, daha az yetenekli e-posta istemcilerine yönelik ekleri, HTML e-postasını ve çoğunlukla e-postanın ek düz metin sürümünü göndermemize olanak tanır. Bu MIME bölümlerinin her birinde, e-posta istemcisinin Content-Transfer-Encoding' and İçerik-Türü' için başlıklar eklemesi ve uygun karakter kümesini eklediğinden emin olması gerekir. Wikipedia, bir özellik karşılaştırma tablosunda 50'den fazla farklı e-posta istemcisini listeler. Tüm bu istemcilerin uluslararası karakterleri tam olarak aynı şekilde ele aldığına bahse girer miydiniz? yapmazdım.

Alan isimleri

90'ların ortalarında, insanlar alan adlarında uluslararası karakterlere izin vermeyi düşünmeye başladı.

DNS sistemi başlangıçta (ve yine de) alan adlarında yalnızca 7 bit ASCII kullanımına izin verir; bu, hiçbir uluslararası karakterin gerçekten mümkün olmadığı anlamına gelir. Yani aynı eski sorunun yeniden çözülmesi gerekiyordu. Ancak, alıntılanan yazdırılabilirleri yeniden kullanmak yerine, IETF bunu düşündü ve daha akıllıca çok önemli bir adım olan Punycode'u kullanarak ortaya çıktı.

Punycode, herhangi bir 8, 16 veya 32 bit (evet, otuz iki) karakterin yalnızca orijinal 7-bit ASCII tablosunda bulunan harfler, rakamlar ve kısa çizgiler kullanılarak kodlanmasına izin verir. Örneğin, karidesli sandviçin İsveççe karşılığı “raksmorgas”tır. Zayıf kodda bu, “xn--rksmrgs-5wao1o” olarak temsil edilecektir.

Yani dışarı çıkıp raksmorgas.com alan adını (şu anda mevcut) satın alacak olsaydınız, aslında xn--rksmrgs-5wao1o.com'u satın alıyor olurdunuz. Ancak tüm modern tarayıcılar onu doğru bir şekilde “raksmorgas.com” olarak gösterecektir.

Buradaki akıllıca şey, genişletilmiş ASCII ile mümkün olan 256 karakterden çok daha büyük bir karakter tablosundan karakterleri temsil etmeye izin vermekti. Böyle bir karakter tablosu gerçek bir çekiş kazanmaya başlamıştı.

Endüstrinin diğer bölümlerinde, sonunda birileri belgelerinde, e-postalarında ve web sayfalarında gobbledygook görmekten bıktı ve tüm bu kodlamaları birleştirmek için Unicode oluşturmaya karar verdi.

Unicode'u girin

Unicode gerçekten başka bir karakter kodlama türüdür, yine de bit -> karakter aramasıdır. Unicode ve ASCII arasındaki temel fark, Unicode'un karakterlerin 32 bit genişliğe kadar olmasına izin vermesidir. Bu 4 milyardan fazla benzersiz değer. Ancak çeşitli nedenlerle bu alanın tamamı kullanılmayacak, aslında Unicode'da yalnızca 1.111.998 karakter olacaktır. Ama bu herkes için yeterli olmalı.

Ancak Unicode ile tüm belgelerim, e-postalarım ve web sayfalarım ASCII'ye kıyasla 4 kat daha fazla yer kaplamaz mı? Neyse ki hayır. Unicode ile birlikte karakterleri temsil etmek veya kodlamak için çeşitli mekanizmalar gelir. Bunlar öncelikle, boyut sorununa gerçekten akıllı bir yaklaşım getiren UTF-8 ve UTF-16 kodlama şemalarıdır.

UTF-8 gibi Unicode kodlama şemaları, bitlerini nasıl kullandıkları konusunda daha verimlidir. UTF-8 ile, bir karakter 1 bayt ile temsil edilebiliyorsa, kullanacağı tek şey budur. Bir karakterin 4 bayta ihtiyacı varsa 4 bayt alır. Buna değişken uzunluk kodlaması denir ve bellek açısından daha verimlidir. Unicode kodlamaları, basitçe bir yazılım parçasının Unicode standardını nasıl uyguladığıdır.

Adam Hooper'ın dediği gibi:

UTF-8 yerden tasarruf sağlar. UTF-8'de “C” gibi yaygın karakterler 8 bit alırken, “💩” gibi nadir karakterler 32 bit alır. Diğer karakterler 16 veya 24 bit alır. Bunun gibi bir blog yazısı UTF-8'de UTF-32'ye göre yaklaşık dört kat daha az yer kaplar. Böylece dört kat daha hızlı yüklenir.

UTF-8, web'de karşılaşacağınız açık ara en yaygın kodlamadır. UTF-8 ile ilgili harika olan şey, ilk 128 kod noktasının ASCII ile tamamen aynı olmasıdır. Yani UTF-8, eğer İngilizce konuşuyorsanız, ASCII ile tamamen aynıdır.

Bunların hepsi, emoji 🚀 nedeniyle günümüzde ve çağımızda önemlidir. Sonuçta emojiler sadece karakterlerdir – 'a' veya 'Z' harfi gibi. Unicode, ihtiyaç duyduğu bit miktarını kullanacak kadar esnek olduğundan, Unicode karakter kümelerine emoji kolayca eklenebilir.

Unicode standardı artık 13.1 sürümünden itibaren 144.076 karakteri kapsamaktadır. Tüm favori emojilerinizin yanı sıra gezegendeki hemen hemen her dilde kullanılan karakterleri içerir.

Unicode Kod Noktaları

Unicode karakterlere kod noktalarına göre başvurulabilir. Bu Yığın Taşması makalesi, bir kod noktasının ne olduğunu açıklamak için iyi bir iş çıkarır:

Bir kod noktası, bilginin atomik birimidir (indirgenemez birim). Metin, bir dizi kod noktasıdır. Her kod noktası, Unicode standardı tarafından anlam verilen bir sayıdır.

Geçerli Unicode standardı 1.114.112 kod noktası tanımlar – bu çok fazla 🍝 demektir. Unicode ayrıca tüm bu kod noktalarını 17 düzleme veya gruba ayırır. Unicode'daki dahili çalışmalar hakkında her şeyi bilmemize gerek yok ama nereden geldiğini anlamak yardımcı oluyor.

Kod noktalarına erişmek için aşağıdaki sözdizimini kullanıyoruz:

 U+(hexadecimal number of code point)

Onaltılık numaralandırma sistemi, büyük sayılara başvurmanın daha kısa bir yolu olduğu için kullanılır. Bu nedenle emoji tablolarında U+1F4A9 veya \u1F4A9 gibi şeyler göreceksiniz.

Örneğin:

Karakter altıgen İkili
💩 U+1F4A9 0001 1111 0100 1010 1001

İşleri daha karmaşık hale getirmek için bazı karakterler kod noktalarının bir kombinasyonu olarak ifade edilebilir.

e, Unicode'da U+0065 (LATİN KÜÇÜK E MEKTUBU) ve ardından U+0301 (AKUT AKSAM BİRLEŞTİRİLMESİ) olarak gösterilebilir, ancak aynı zamanda önceden oluşturulmuş U+00E9 (AKUTLU LATİN KÜÇÜK E MEKTUBU) olarak da temsil edilebilir.

JavaScript'in Unicode uygulamasına baktığımızda bununla ilgili daha fazla şey öğreneceğiz, ancak karmaşık olsun ya da olmasın, Unicode, karakter kodlamaları için uluslararası standarttır ve hepsi bu kadar değildir 🌹☀️.

Unicode ile ilgili sorunlar

Farklı programlama dilleri, işletim sistemleri, hatta iOS Uygulamaları bile Unicode'u farklı şekilde ele alıyor ve Unicode'un gerçekte ne olduğu konusunda hala çok fazla kafa karışıklığı var. Eve yakın bazı örneklere bakalım.

PHP

Odadaki ElePHPant ile başlayacağız, PHP. PHP'nin dizeler dokümantasyon sayfasında, yalnızca 256 karakterlik bir kümeyi desteklediğini iddia ediyor. Bunun gerçekten anlamı, PHP'nin dizeler için 1 bayt = 1 karakter olduğunu varsaymasıdır. Bu aslında WP Migrate DB Pro'daki Tema ve Eklenti Dosyaları Eklentisi için toplu işlem özelliği üzerinde çalışırken karşılaştığım bir şey.

Bir dizgenin bayt cinsinden boyutunu almak istiyorsanız, karakterleri saymanız yeterlidir! PHP'de bir dize için strlen() , esasen kaç bayt kapladığını gösterir. Serin.

Buuuut, bu kötü çocuğu içeren bir dizeye ne dersiniz – 🔥. Bu kaç bayt olurdu? 1?

 echo strlen( '🔥' ); // Outputs: 4

Eve git PHP sarhoşsun .

Burası PHP'nin çok baytlı dize işlevlerinin devreye girdiği yerdir. Karakter cinsinden okunaklı dize uzunluğunu 🔥 elde etmek için mb_strlen() kullanmanız gerekir.

 echo mb_strlen( '🔥' ); // Outputs: 1

Serin! Bu işe yarar. Ama standart strlen() ile ilgili olarak 4'ün uzunluğu neydi? Daha önce bahsettiğim gibi, PHP 1 karakter = 1 bayt düşünür, bu yüzden dahili olarak bir dizgenin bellek boyutunu kontrol eder. 🔥 emojisi aslında 4 bayt bellek kaplıyor!

4kb bellek

Ne hafıza domuzu 🐷.

Gerçekte, PHP yalnızca, dizeleri manipüle ediyorsanız Unicode'u bozar. Yalnızca dize alıyor veya çıktı alıyorsanız, PHP umursamıyor ve gayet iyi çalışacaktır. Ancak, alt dizeler veya dize uzunlukları elde etmeye çalışıyorsanız, çok baytlı işlevlere bağlı kalın.

Ve bahsetmeye değer, PHP 8'de bile, çok baytlı dize kitaplığı, varsayılan olarak açık olmayan mbstring uzantısı aracılığıyla teslim edilir. PHP'yi kendiniz kurarken bu uzantıyı etkinleştirdiğinizden emin olun. En saygın WordPress ana bilgisayarları ve kontrol panelleri, kendi kontrol panelimiz SpinupWP dahil olmak üzere etkinleştirecektir.

PHP'de sahte arkadaşlar

PHP işlevleri utf8_encode() ve utf_decode() , PHP'de Unicode dizeleri ile çalışırken gerçekten yararlı olacakları gibi geliyor. Pekala, sadece PHP'de varsayılan karakter kodlaması olan ISO-8859-1 ASCII kodlamasıyla çalıştığınızdan %100 emin olduğunuz sürece. PHP kılavuzunun doğru bir şekilde işaret ettiği gibi:

ISO-8859-1 karakter kodlamasını kullanıyor olarak işaretlenen birçok web sayfası aslında benzer Windows-1252 kodlamasını kullanır…

Doğru ASCII karakter kodlamasını kullanarak dizeleri UTF-8'e ve UTF-8'den doğru şekilde dönüştürdüğünüzden kesinlikle emin olmanız gerekiyorsa, kullanımda olan karakter kodlamalarını açıkça tanımlamaya izin verdiği için mb_convert_string() işlevine bir göz atmalısınız.

Diğer mb_* işlevlerinde olduğu gibi, mb_convert_string() işlevi de mbstring uzantısı aracılığıyla sağlanır.

JavaScript

JavaScript motorları, başka bir değişken uzunluk kodlaması olan UTF-16'yı dahili olarak kullanır. Hatırlarsanız, UTF-16, kullanılan en düşük bit miktarının 16 olması dışında UTF-8'e çok benzer. 'C' gibi basit karakterler 16 bit, süslü karakterler ise 32 bit kullanır.

JavaScript'te, dizeler UTF-16 kod birimleri olarak kabul edilir, bunun anlamı, bir karaktere başvuruda bulunmak için iki kod noktası kullanmanız gerekebileceğidir.

 let poop = '💩' ; console .log( poop.length ); // Outputs 2

PHP'nin strlen() benzer şekilde, JavaScript'in uzunluk özelliği bir karakterin kod birimi uzunluğunu döndürür. JavaScript UTF-16 kodlama türünü kullandığından emoji gibi karmaşık karakterlerin uzunluğu 2 olacaktır.

 let poop = '\uD83D\uDCA9' console .log( poop ) // 💩 console .log( poop.length ) // 2

Emojileri veya diğer karakterleri onaltılık çıkış değerlerine dönüştürmek için bu kullanışlı aracı kullanabilirsiniz.

String.prototype.slice() veya String.prototype.substring() gibi işlevleri kullanırken bunu akılda tutmak önemlidir. Temel olarak, JavaScript'te dizeleri kod birimleri olarak düşünün ve iyi olacaksınız. ES2015'ten itibaren String.prototype.normalize mevcuttur. Dizeleri standartlaştırılmış bir Unicode biçimine dönüştürmenize olanak tanır. Bu, yanlış kodlanmış dizeleriniz varsa veya dize uzunluklarını karşılaştırıyorsanız yararlıdır.

JavaScript, Unicode ve kod birimleri konusu geniş bir konudur, ancak daha fazlasını öğrenmek istiyorsanız Dimitri'nin gönderisini okumanızı tavsiye ederim. Bu bir göz açıcı.

MySQL

MySQL'in Unicode ile ilgili sorunları, karakter kodlama uyumluluğu sorunlarıyla ilk karşılaştığım yer. Aynı zamanda saçlarımı ilk kaybetmeye başladığım zamandı 😢.

PHP gibi MySQL de UTF-8'i veya gerçekten Unicode'u tam olarak desteklemez. MySQL'in utf8 kodlaması gerçekten UTF-8 değil. Hepimizin eskiden kullandığı utf8 kodlaması yalnızca 3 bayt kullanır. Niye ya? Pekala, kimin tek bir karakteri temsil etmek için 3 bayttan fazlasına, 24 TAM BİT'e ihtiyacı olabilir! Nedeni uzun bir hikaye (duymak isterseniz Adam'ın makalesini okumanızı öneririm), ancak 2010'da bize utf8mb4 kodlamasını getiren bir düzeltme yapıldı.

utf8mb4 karakter seti eklendi. Bu, utf8'e benzer, ancak kodlaması, ek karakterleri desteklemek için karakter başına dört bayta kadar izin verir.

Güzel. Yani utf8 karakter setini kullanıyorsanız süslü bir 😬 görmezsiniz.

WordPress çekirdek gözetmenleri bunu 2015'te fark etti ve utf8mb4 yeni yüklemeler ve mümkünse yeni kodlamayı kullanmak için yükseltilmiş tablolar için varsayılan yaptı. Profesyonel ipucu, WordPress veritabanı bilgisinde daha derin bir dalış için WordPress veritabanı kılavuzumuza göz atın.

Bir veritabanı taşıma eklentisi üzerinde çalışan biri olarak, bu beni bir kereden fazla ısırdı ve sık sık utf8mb4 kodlu bir veritabanından utf8 kodlu bir veritabanına geçiş sorunlarıyla ilgili olarak bize e-posta gönderen müşterilerimiz var.

Teşekkürler MySQL!

Bir geçici çözümümüz var, ancak en iyi seçeneğiniz, geçişe dahil olan her iki tarafın da utf8mb4 karakter kümesini kullandığından emin olmaktır.

TL; DR

Unicode, dünyanın tüm dilleri, glifleri ve emojileri için ortak, devasa bir karakter kümesidir. UTF kodlama ailesi, bilgisayarların hangi bit dizisinin hangi karakter olarak temsil edilmesi gerektiğini nasıl bildiğidir. Ancak, her programlama dili, uygulaması ve işletim sistemi Unicode'u farklı şekilde uygular ve destekler (eğer varsa). Burası geliştiricinin işinin eğlenceli hale geldiği yer 😬.

Protip: Dizelerinizin hangi kodlamayı kullandığını bilin ve bilirsiniz, her yerde aynı kodlamayı kullanın!

İşinizde Unicode ile ilgili sorunlarınız mı var? Yukarıda atladığım bir şey var mı? Yorumlarda bize bildirin.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

Divi's Theme Builder ile Özel Global Başlık Nasıl Oluşturulur

Artık Tema Oluşturucu burada olduğuna göre, web sitenizi A'dan Z'ye kurmanıza yardımcı olacak yeni eğitimlere dalmak için sabırsızlanıyoruz. Buna Divi'nin yerleşik seçeneğini kullanarak özel başlıklar oluşturma da dahildir. Bu eğitimde Divi's Theme Builder'ı kullanarak global bir başlık oluşturmaya odaklanacağız. Bu sayfaya veya gönderiye farklı bir başlık atamadıysanız, web sitenizin her yerinde genel bir başlık görünecektir.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir