1 puan yazan GN⁺ 4 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • ASCII'de Z 90, a ise 97 konumuna yerleştirilmiştir; aradaki 6 karakter sayesinde büyük ve küçük harflerin kod farkı 32 olur
  • 32, 2^5 olduğu için A 65 ve a 97 gibi karşılık gelen büyük-küçük harfler her zaman yalnızca 00100000 bitinde farklıdır
  • Bu yerleşim sayesinde 32nin bit düzeyinde terslenmiş değeriyle AND yapılırsa büyük harfe çevirme, 32 ile OR yapılırsa küçük harfe çevirme, 32 ile XOR yapılırsa büyük-küçük harfi tersine çevirme mümkündür
  • Alfabenin sırası, karakter koduna 31 ile AND uygulanıp yalnızca alt 5 bit bırakılarak elde edilebilir; A/a 1, Z/z ise 26 olur
  • ASCII, yalnızca 128 kod noktasını ifade eden erken dönem bir 7 bit karakter kodlamasıdır; bugün kullanılan Unicode'un ilk 128 kod noktası ASCII ile aynıdır

ASCII yerleşimi ve 32 farkı

  • ASCII tablosunda büyük Z harfinin kod değeri 90, küçük a harfininki ise hemen sonraki değer değil 97'dir
  • Arada [ \ ] ^ _ ` olmak üzere 6 karakter bulunur
  • İngiliz alfabesi 26 harften oluşur ve bu 6 karakter eklendiğinde 26 + 6 = 32 elde edilir
  • 32, 2^5 değerine karşılık geldiği için büyük ve küçük harf eşleşmeleri belirli tek bir bit farkına göre hizalanır
  • Örneğin A, 65 yani 01000001; a ise 97 yani 01100001'dir ve iki değer arasındaki fark 32'dir

ASCII ile Unicode arasındaki ilişki

  • ASCII, erken dönem karakter kodlama yöntemlerinden biridir ve yalnızca 7 bit kullanarak 2^7 = 128 kod noktasını ifade eder
  • 128 kod noktası, insanların kullandığı tüm karakterleri kapsamak için yetersizdir; özellikle on binlerce karakter içeren Çince gibi dilleri kapsamaya yetmez
  • Günümüzde standart karakter kümesi olarak Unicode kullanılır ve UTF-8 ile UTF-16 gibi çeşitli kodlamalara sahiptir
  • Unicode'un ilk 128 kod noktası ASCII ile aynıdır

Büyük-küçük harfi ayıran 5. bit

  • Büyük harf ve ona karşılık gelen küçük harf ikilik düzende karşılaştırıldığında, her zaman 32ye karşılık gelen bit değişir
65  = 01000001 = A
97  = 01100001 = a

66  = 01000010 = B
98  = 01100010 = b

67  = 01000011 = C
99  = 01100011 = c
  • 32, ikilik düzende 00100000'dır ve büyük-küçük harf farkını oluşturan tek bit budur
  • ASCII'deki alfabe yerleşimi, bit işlemleriyle büyük-küçük harf dönüşümünü kolaylaştıracak şekilde düzenlenmiştir

Bit işlemleriyle büyük-küçük harf işlemek

  • Büyük harfe dönüştürme

    • Bir karakteri büyük harfe çevirmek için 32nin bit düzeyindeki ters değeriyle bit bazında AND yapılır
0 1 1 0 0 0 0 1 (97 = 'a')
& 1 1 0 1 1 1 1 1 (mask)
-------------------
0 1 0 0 0 0 0 1 (65 = 'A')
  • a üzerinde uygulandığında 97, 65'e dönüşür ve A olur
  • Zaten büyük olan A üzerinde aynı işlem uygulanırsa sonuç yine A olur
  • Küçük harfe dönüştürme

    • Bir karakteri küçük harfe çevirmek için 32 ile bit bazında OR yapılır
0 1 0 0 0 0 0 1 (65 = 'A')
| 0 0 1 0 0 0 0 0 (32)
-------------------
0 1 1 0 0 0 0 1 (97 = 'a')
  • A üzerinde uygulandığında 65, 97'ye dönüşür ve a olur
  • Zaten küçük olan a üzerinde aynı işlem uygulanırsa sonuç yine a olur
  • Büyük-küçük harfi tersine çevirme

    • Büyük-küçük harfi ters çevirmek için 32 ile bit bazında XOR yapılır
0 1 1 0 0 0 0 1 (97 = 'a')
^ 0 0 1 0 0 0 0 0 (32)
-------------------
0 1 0 0 0 0 0 1 (65 = 'A')

0 1 0 0 0 0 0 1 (65 = 'A')
^ 0 0 1 0 0 0 0 0 (32)
-------------------
0 1 1 0 0 0 0 1 (97 = 'a')
  • a, A'ya; A ise a'ya dönüşür

Alt 5 bit ile alfabe sırasını elde etmek

  • Alfabe sırası, karakter koduna 31 ile bit bazında AND uygulanarak bulunabilir
0 1 0 0 0 0 0 1 (65 = 'A')
& 0 0 0 1 1 1 1 1 (31)
-------------------
0 0 0 0 0 0 0 1 (1)

0 1 1 1 1 0 1 0 (122 = 'z')
& 0 0 0 1 1 1 1 1 (31)
-------------------
0 0 0 1 1 0 1 0 (26)
  • 31, ikilik düzende 00011111 olduğundan öndeki bitleri temizler ve yalnızca alt 5 biti bırakır
  • ASCII'de alfabetik karakterlerin alt 5 biti, harfin alfabedeki konumuyla örtüşür
  • A/a 00001 ile biter ve 1 olur; B/b 00010 ile biter ve 2 olur; Z/z ise 11010 ile biter ve 26 olur
  • ASCII karakter kodlarında c & 31, c % 32 ile aynıdır
  • 32, 2'nin kuvveti olduğu için 31 ile maskeleme, 32lik grupları kaldırıp yalnızca kalan kısmı korur
'A' = 65  → 65 % 32 = 1
'B' = 66  → 66 % 32 = 2
...
'Z' = 90  → 90 % 32 = 26
'a' = 97  → 97 % 32 = 1
'b' = 98  → 98 % 32 = 2
...
'z' = 122 → 122 % 32 = 26

1 yorum

 
GN⁺ 4 시간 전
Lobste.rs görüşleri
  • Açıklama fena değil ama bence https://garbagecollected.org/2017/01/31/four-column-ascii/ bunu daha iyi anlatıyor.
    Mesele sadece Shift değil, Ctrl de işin içinde. Örneğin Tab, Ctrl-I’dir; çünkü I 1001001’dir ve Ctrl ilk biti maskeleyip Tab’ın 0001001 değerini bırakır

  • 1960’lardaki üreticiler gibi elektronik mantık yerine elektromekanik mantık kullanıyorsanız, bit paired keyboard uygulamak çok daha kolaydır.
    Shift tuşunun tek yapması, ASCII karakterde tek bir biti değiştirmektir. Bugün her klavyeye genel amaçlı CPU koyuyoruz ve mantık neredeyse bedava, ama genel amaçlı bilgisayarların bir oda büyüklüğünde olduğu dönemde böyle bir çözüm çok daha pahalıydı

  • Yazı, ASCII düzeninin motivasyonu olarak büyük/küçük harf dönüşümünün bit işlemleri ile verimli biçimde uygulanabilmesini öne sürüyor; ama bunun değeri tarihsel açıdan bir yana, bugün oldukça sınırlı görünüyor.
    a→A dönüşümü yalnızca basit metinde çalışır ve ISO-8859-1 ya da Unicode bu düzeni ü, ç gibi karakterlere kısmen genişletse bile büyük/küçük harf dönüşümü bölgeye, bağlama ve döneme göre değişir. ß ya da ï için doğru büyük/küçük harf eşlemesi; dile, düzenleyici kurumlara, kullanım bölgesine ve zamana bağlıdır
    Unicode, https://www.unicode.org/charts/case/ gibi büyük/küçük harf eşleme ve folding tabloları sunarak yaygın durumlarda oldukça yakın sonuç verir; ama insan politikalarının devreye girdiği bir alan olduğu için karmaşıklık fiilen sınırsızdır ve doğru sonuç için özel yazılım gerekebilir
    Günümüzde Unicode’un yalnızca ilk 2⁷ kod noktasına sınırlı olduğunu garanti edemiyorsanız 0b0010_0000 ofseti kolayca bozulur ve tek bitlik işlemden daha pahalı kod yolları kaçınılmaz olur. CPython’da bile ''.upper, unicode_upper{,_impl} içindeki ASCII hızlı yolundan geçer ama pratikte branch, inline function, struct erişimi, birden fazla function ve function, macro üzerinden gidip bir table lookup yapar
    Modern dillerde ''.upper uygulamaları genel olarak benzer bir karmaşıklık düzeyine sahip olacaktır ve derleyici optimize etse bile modern yaklaşımın tek bitlik işlemden daha pahalı olması kaçınılmaz görünüyor. Bu tasarımın avantajı muhtemelen ancak ham ikili verilerde ya da 2⁷ altı kod noktalarına sahip Unicode verisini içeren dtype=uint8 bir numpy.ndarray üzerinde aritmetik işlem yapan özel yazılımlarda belirginleşir
    Benim merak ettiğim şu: Bu tasarım tercihinin tek motivasyonunun yazıda söylendiği şey olduğunu varsayarsak, o dönemde 128 baytlık lookup table gibi bir alternatif de vardı; peki bilgisayar tarihinde tek bitlik işlemin 128 baytlık tablo erişiminden daha verimli ya da daha uygulanabilir olduğu dönem tam olarak ne zamandı?

    • Uzun süre başarılı olmuş kitlesel teknolojileri kurcalayınca bu tür bit hilelerine sık rastlanıyor.
      Belli bir andaki tasarım tercihi, daha sonra bozulacak varsayımlara dayanarak bir şeyin biçimini sabitliyor ve sonradan genişletmeyi zor ya da imkânsız hale getiriyor. Son dönemdeki IPv6 yazılarında da, IPv4 ve IPv6 için kendi zamanlarında doğru olan tercihlerin bugün nasıl devasa bir yüke dönüştüğü görülüyor
      İyi niyetli bakarsak, bu tür kararlar risk ve kazanç tartılarak verilmiştir. “Bir karakteri büyütmek için tek bitlik işlem çok daha hızlıysa, günün birinde Japonca kullanıcı çıkınca bozulma riskine değer” gibi
      Bugünden bakınca 1976’daki bir tercih 2026’daki hayatı zorlaştırıyor; ama 1976’da bilgisayara hiç sahip olamadıysanız o avantajı zaten hiç yaşamadınız, size sadece dezavantaj kaldı. Bu bencilliği bir kenara bırakırsak, 20 yıl sonra da popüler olacak yazılım geliştirirken böyle tercihlerin sürdürülebilirliğini nasıl daha iyi öngörebileceğimizi merak ediyorum
    • ASCII’ye özel büyük/küçük harf duyarsız kodlama kullanan çok sayıda ağ protokolü var; bu yüzden hızlı, bit düzeyinde tolower hâlâ işe yarıyor. https://dotat.at/@/2022-06-27-tolower-swar.html
  • En azından ASCII’de harfler ardışık. EBCDIC’te aralık 0x40 (64) ve ASCII ile karşılaştırınca 9 karakterlik iki satır ile 8 karakterlik bir satırın üst üste dizilmiş hali gibi.
    https://en.wikipedia.org/wiki/EBCDIC

  • IRC takma adlarının ASCII büyük/küçük harf duyarsız olması yüzünden foo{ ile foo[ aynı, bar| ile bar\ aynı sayılırdı; bunu hatırladım
    Bu yüzden bazı istemcilerin hâlâ kafasının karışmasına şaşırmam