1 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Dalam ASCII, Z ditempatkan di 90 dan a di 97, dan berkat 6 karakter di antaranya selisih kode antara huruf besar dan huruf kecil menjadi 32
  • Karena 32 adalah 2^5, pasangan huruf besar-kecil yang saling bersesuaian seperti A 65 dan a 97 selalu hanya berbeda pada satu bit 00100000
  • Berkat susunan ini, melakukan AND dengan nilai invers bit dari 32 akan mengubah ke huruf besar, melakukan OR dengan 32 akan mengubah ke huruf kecil, dan melakukan XOR dengan 32 akan membalik huruf besar-kecil
  • Urutan alfabet bisa diperoleh dengan melakukan AND pada kode karakter dengan 31 sehingga hanya 5 bit terendah yang tersisa; hasilnya A/a menjadi 1 dan Z/z menjadi 26
  • ASCII adalah pengodean karakter awal yang hanya memakai 7 bit untuk merepresentasikan 128 code point, dan 128 code point pertama pada Unicode yang digunakan saat ini identik dengan ASCII

Susunan ASCII dan selisih 32

  • Pada tabel ASCII, nilai kode huruf besar Z adalah 90, dan huruf kecil a ditempatkan di 97, bukan pada nilai berikutnya
  • Di antaranya ada 6 karakter: [ \ ] ^ _ `
  • Alfabet Inggris terdiri dari 26 huruf, dan jika ditambah 6 karakter ini maka 26 + 6 = 32
  • Nilai 32 setara dengan 2^5, sehingga hubungan huruf besar dan kecil disusun agar berbeda hanya pada satu bit tertentu
  • Misalnya, A adalah 65 atau 01000001, sedangkan a adalah 97 atau 01100001, dan selisih kedua nilai ini adalah 32

Hubungan ASCII dan Unicode

  • ASCII adalah salah satu metode pengodean karakter awal, dan hanya menggunakan 7 bit untuk merepresentasikan 2^7 = 128 code point
  • Sebanyak 128 code point tidak cukup untuk memuat semua karakter yang digunakan manusia, terutama bahasa seperti Tionghoa yang memiliki puluhan ribu karakter
  • Saat ini, himpunan karakter standar yang digunakan adalah Unicode, dengan berbagai encoding seperti UTF-8 dan UTF-16
  • 128 code point pertama pada Unicode identik dengan ASCII

Bit ke-5 yang membedakan huruf besar dan kecil

  • Jika huruf besar dan huruf kecil pasangannya dibandingkan dalam biner, bit yang setara dengan 32 selalu berubah
65  = 01000001 = A
97  = 01100001 = a

66  = 01000010 = B
98  = 01100010 = b

67  = 01000011 = C
99  = 01100011 = c
  • 32 dalam biner adalah 00100000, dan satu bit inilah yang menciptakan perbedaan antara huruf besar dan huruf kecil
  • Susunan alfabet pada ASCII dibuat agar konversi huruf besar-kecil mudah dilakukan dengan operasi bit

Menangani huruf besar-kecil dengan operasi bit

  • Mengubah ke huruf besar

    • Untuk mengubah karakter menjadi huruf besar, lakukan bit AND dengan nilai invers bit dari 32
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')
  • Jika diterapkan ke a, 97 berubah menjadi 65 sehingga menjadi A
  • Jika operasi yang sama diterapkan pada A yang sudah huruf besar, hasilnya tetap A
  • Mengubah ke huruf kecil

    • Untuk mengubah karakter menjadi huruf kecil, lakukan bit OR dengan 32
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')
  • Jika diterapkan ke A, 65 berubah menjadi 97 sehingga menjadi a
  • Jika operasi yang sama diterapkan pada a yang sudah huruf kecil, hasilnya tetap a
  • Membalik huruf besar-kecil

    • Untuk membalik huruf besar-kecil, lakukan bit XOR dengan 32
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 berubah menjadi A, dan A berubah menjadi a

Mendapatkan urutan alfabet dari 5 bit terendah

  • Urutan alfabet dapat diperoleh dengan melakukan bit AND pada kode karakter dengan 31
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 dalam biner adalah 00011111, sehingga bit di depan dihapus dan hanya 5 bit terendah yang dipertahankan
  • Pada ASCII, 5 bit terendah dari karakter alfabet kebetulan sesuai dengan posisi huruf dalam alfabet
  • A/a berakhir dengan 00001 sehingga menjadi 1, B/b berakhir dengan 00010 sehingga menjadi 2, dan Z/z berakhir dengan 11010 sehingga menjadi 26
  • Pada kode karakter ASCII, c & 31 sama dengan c % 32
  • Karena 32 adalah pangkat dua, melakukan masking dengan 31 menghapus kelompok berbasis 32 dan hanya menyisakan sisanya
'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 komentar

 
GN⁺ 4 jam lalu
Opini di Lobste.rs
  • Penjelasannya cukup baik, tetapi rasanya https://garbagecollected.org/2017/01/31/four-column-ascii/ menjelaskan ini dengan lebih baik
    Ini bukan cuma soal Shift, tetapi juga terkait Ctrl. Misalnya, Tab adalah Ctrl-I, karena I adalah 1001001 dan Ctrl mem-mask bit pertama sehingga menyisakan 0001001, yaitu Tab

  • Jika memakai logika elektromekanis alih-alih logika elektronik seperti para produsen pada 1960-an, bit paired keyboard jauh lebih mudah diimplementasikan
    Tombol Shift cukup men-toggle satu bit pada karakter ASCII. Sekarang semua keyboard punya CPU serbaguna dan logikanya pada dasarnya gratis, tetapi pada masa ketika komputer serbaguna sebesar satu ruangan, solusi seperti itu jauh lebih mahal

  • Tulisan itu mengajukan bahwa motivasi susunan ASCII adalah agar konversi huruf besar-kecil bisa diimplementasikan secara efisien dengan operasi bit, tetapi nilainya tampak cukup tipis untuk konteks modern, meski mungkin masuk akal secara historis
    Konversi a→A hanya berlaku untuk teks sederhana, dan walaupun ISO-8859-1 atau Unicode sebagian memperluas susunan itu ke karakter seperti ü dan ç, konversi huruf besar-kecil berubah tergantung wilayah, konteks, dan periode waktu. Pasangan huruf besar/kecil yang benar untuk ß atau ï bergantung pada bahasa, badan regulator, wilayah penggunaan, dan zamannya
    Unicode menyediakan tabel pemetaan dan pelipatan huruf besar-kecil seperti https://www.unicode.org/charts/case/ yang memberi jawaban yang cukup mendekati untuk kasus umum, tetapi karena ini masalah yang melibatkan kebijakan manusia, kompleksitasnya pada praktiknya tak berbatas dan bisa memerlukan perangkat lunak khusus untuk benar-benar tepat
    Saat ini, kecuali Anda bisa menjamin data terbatas hanya pada 2⁷ code point pertama Unicode, offset 0b0010_0000 mudah rusak, dan jalur kode yang lebih mahal daripada satu operasi bit menjadi tak terelakkan. Bahkan di CPython, ''.upper memang melewati jalur cepat ASCII di unicode_upper{,_impl}, tetapi pada praktiknya tetap melalui percabangan, fungsi inline, akses struct, beberapa fungsi dan fungsi, makro, lalu melakukan lookup tabel
    Implementasi ''.upper di bahasa modern umumnya akan memiliki tingkat kompleksitas serupa, dan meskipun compiler mengoptimalkan, pendekatan modern tampaknya tetap tak bisa semurah satu operasi bit. Keuntungan desain ini kemungkinan hanya benar-benar menonjol dalam perangkat lunak khusus, misalnya melakukan operasi aritmetika pada numpy.ndarray dengan dtype=uint8 yang berisi biner mentah atau data Unicode dengan code point di bawah 2⁷
    Yang membuat penasaran adalah ini: jika kita mengasumsikan satu-satunya motivasi pilihan desain ini adalah seperti yang disebut tulisan itu, saat itu sebenarnya sudah ada alternatif berupa lookup table 128 byte; lalu kapan dalam sejarah komputasi satu operasi bit lebih efisien atau lebih layak diwujudkan daripada lookup tabel 128 byte?

    • Jika menggali teknologi populer yang bertahan lama, bit trick seperti ini sering muncul
      Sebuah pilihan desain pada suatu masa mengunci bentuk sesuatu dengan mengandalkan asumsi yang nantinya akan patah, lalu membuat perluasan berikutnya sulit atau mustahil. Dalam tulisan-tulisan terbaru tentang IPv6 juga terlihat bahwa pilihan IPv4 dan IPv6 yang dulu benar justru menjadi beban besar saat ini
      Jika dilihat dengan murah hati, keputusan seperti ini pasti diambil setelah menimbang risiko dan manfaat. Semacam, “satu operasi bit untuk mengubah satu karakter menjadi huruf besar jauh lebih cepat, jadi layak menanggung risiko bahwa ini akan rusak suatu hari nanti ketika ada pengguna bahasa Jepang”
      Dari sudut pandang orang modern, keputusan tahun 1976 membuat hidup tahun 2026 lebih sulit, tetapi jika pada 1976 Anda bahkan belum punya komputer, Anda tidak pernah menikmati manfaatnya dan hanya mewarisi kelemahannya. Jika mengesampingkan sikap egois itu, saya penasaran bagaimana kita bisa lebih baik memprediksi keberlanjutan pilihan seperti ini saat membuat perangkat lunak yang masih akan populer 20 tahun lagi
    • Banyak protokol jaringan memakai encoding abai huruf besar-kecil ASCII saja, jadi tolower cepat berbasis bit masih berguna hingga sekarang. https://dotat.at/@/2022-06-27-tolower-swar.html
  • Setidaknya dalam ASCII, huruf-hurufnya berurutan. EBCDIC punya jarak 0x40 (64), dan dibandingkan ASCII bentuknya seperti dua baris berisi 9 karakter dan satu baris berisi 8 karakter yang ditumpuk ke atas-bawah
    https://en.wikipedia.org/wiki/EBCDIC

  • Saya jadi teringat nickname IRC yang mengabaikan huruf besar-kecil ASCII, sehingga foo{ dianggap sama dengan foo[ dan bar| sama dengan bar\\
    Saya tidak akan terkejut kalau beberapa klien masih bingung karena ini