Selasa, 31 Desember 2024

Menengok Kembali Tahun 2024

Hai, hai!

Ini hari terakhir tahun 2024 Masehi. Pada masa-masa ini, orang-orang biasa mengepos kilas balik tentang diri mereka. Ada yang mengepos Spotify Wrapped, YouTube Music Recap, bahkan GoJek Wrapped. Bukan, bukan itu yang akan kubahas kali ini. Aku ingin bercerita hal-hal yang kualami pada tahun ini.

Apakah aku menjadi orang yang lebih baik tahun ini? Mungkin orang lain yang lebih tepat untuk menilainya. Hanya saja, aku merasa lebih baik tahun ini. Aku belajar banyak hal baru, terutama tentang interaksi antar-manusia, selain studi ilmu komputer tentunya. Oh, omong-omong tentang perkuliahan, ....

Perkuliahan

Pada semester ke-2 lalu, aku mengambil mata kuliah Jaringan Komputer Lanjut/Jarkom Lanjut (wajib) dan Analisis Data Spasial Lanjut/ADSL (pilihan). Aku mengambil mata kuliah ADSL karena mata kuliah ini berkaitan dengan tesisku yang membahas data spasial atau citra/bangun.

Yang berkesan dari mata kuliah Jarkom Lanjut adalah tugas kelompok tiap pekan untuk mengulas dua artikel jurnal. Setelah itu, secara bergantian untuk tiap pekan, kelompok yang sesuai jadwalnya akan mempresentasikan hasil ulasan masing-masing. Dari tugas-tugas ini, wawasanku lebih terbuka mengenai dunia jaringan komputer dan banyak metode/algoritma yang ada di balik layar prasarana komunikasi global yang kita gunakan ini, yaitu internet.

Yang berkesan dari mata kuliah ADSL adalah data spasial utamanya. Aku memang suka data spasial, entah citra/foto entah bentuk/bangun. Skripsiku saja berkaitan dengan data spasial (citra satelit dan segmentasinya). Dari mata kuliah ini pula, aku juga jadi mengenal PostGIS, yaitu pengaya PostgreSQL untuk data spasial.

Pada semester ke-3 lalu, aku mengambil mata kuliah Rekayasa Perangkat Lunak Lanjut/RPLL (wajib) dan Komputasi Paralel Lanjut/Komparlan (pilihan). Aku mengambil mata kuliah Komparlan karena mata kuliah ini berkaitan dengan tesisku yang berkaitan dengan komputasi paralel untuk menjalankan metode penelitian untuk tesisku.

Yang berkesan dari mata kuliah RPLL adalah banyaknya teori dasar yang diusulkan menjadi teori besar (grand theory) rekayasa perangkat lunak. Aku juga belajar ulang kembali materi ini yang tidak terlalu kupahami selama kuliah S-1 walaupun aku juga memahami metode formal, mata kuliah pilihan yang kuambil selama kuliah S-1 dan membahas tentang penulisan persyaratan (requirement). Pada paruh kedua semester, mata kuliah ini membahas tentang ontologi. Aku sudah mengenalnya sejak berkenalan dengan Wikidata sehingga cukup bisa memahami materinya.

Yang berkesan dari mata kuliah Komparlan adalah tugas proyek kelompok yang menggunakan setidaknya dua lingkungan. Dengan CPU, ada lingkungan banyak nodus (multi-node) dan banyak inti (multi-core). Selain itu, ada lingkungan GPU dengan kartu grafis tingkat konsumen rumahan dan kartu grafis tingkat institut/universitas (NVIDIA Tesla). Oh, aku juga jadi belajar menggunakan CUDA. Baru kali ini aku berkesempatan menggunakan GPU secara langsung (low-level programming).

Selain itu, tahun ini dimulai untuk mata kuliah spesial Studi Mandiri dan Proposal Tesis. Studi Mandiri bertujuan untuk melakukan penelusuran literatur, mencari gap, dan melakukan ulang percobaan penelitian sebelumnya dengan harapan bisa ditemukan ide untuk tesis. Aku sudah mencoba menyelesaikan studi mandiri pada semester ke-2 lalu. Namun, rupanya, ada yang keliru pada bagian metodenya menurut dosen pembimbingku. Jadi, ya, aku perlu mengulang beberapa percobaan dengan metode yang sudah dibetulkan sehingga perlu memperpanjang mata kuliah ini.

Semester ke-3 ini cukup penuh kegiatan. Aku perlu menyelesaikan mata kuliah Studi Mandiri sekaligus menyusun dokumen untuk mata kuliah Proposal Tesis. Alhamdulillah, proposal tesisku sudah disetujui oleh dosen pembimbingku bulan ini dan jadwal seminar proposalku adalah bulan depan.

Keluarga

Alhamdulillah. Ayahku dan ibuku ikut masuk dalam kloter haji tahun ini! Awalnya, kami mengira bahwa masih tahun depan jadwal ayah-ibuku. Namun, ayahku coba menghubungi dinas agama di kabupatenku dan mendapat informasi bahwa ayah-ibuku masuk kloter haji tahun ini.

Tahun ini tahun yang tepat bagi ayah-ibuku naik haji. Aku sedang libur semester kuliah pada bulan Zulhijah sehingga berkesempatan untuk pulang kampung dan tinggal di rumah selama ayah-ibuku naik haji. Kalau saja selisih beberapa tahun, mungkin aku sedang ujian sehingga belum bisa pulang ketika ayah-ibuku berangkat.

Pada semester ke-3 ini, aku tidak pulang pada tengah semester. Pada semester ke-1 lalu, aku sempat pulang karena ada acara di rumah mbahku. Pada semester ke-2 lalu, aku sempat pulang karena ada Idulfitri. Nah, pada semester ke-3 ini, tidak ada acara yang bisa jadi alasan untukku pulang kampung. Belum lagi ibuku pernah bilang, "Enggak usah pulang sering-sering! Boros!" Ya, sudah, deh.

Oh, satu lagi. Pada tahun ini, aku bertemu seorang perempuan yang kurasa cocok denganku, bahkan bisa jadi teman hidupku (semoga, he-he). Yang mengikuti cerita Instagram-ku pasti sudah pernah baca tulisan/puisi yang kubuat tentang hal ini. Hari-hariku lebih berwarna-lah intinya sejak aku bersama dia.

Lain-Lain

Tahun ini tahun demokrasi. Ada banyak yang dipilih tahun ini. Aku sempat membuat surat keterangan pindah DPT, tetapi kubatalkan karena ternyata aku masih libur pada hari pencoblosan. Aku bisa ikut pemilihan presiden, anggota DPR, dan anggota DPD, tetapi tidak bisa ikut pilkada (bupati) karena aku masih di Depok.

Motorku dimaling! Untuk membantuku selama kuliah di Depok, motor kerabat di Pekalongan dipinjamkan dan dikirim ke Depok untuk kupakai. Namun, pada semester ke-2, saat aku sedang salat Asar di sebuah masjid dekat kantor kelurahan di dekat kos, motorku dicuri. Masih ada rekamannya di tempatku. Aku sudah membuat laporan kehilangan di Polsek Beji. Alhamdulillah, jemaah masjidnya membantuku selama mengurus akibat kejadian pada hari itu.

Penutup

Tahun ini penuh berbagai macam cerita. Tahun ini berisi kegagalan, tetapi juga penuh dengan harapan dan keberhasilan. Semoga hal-hal baik juga datang pada tahun depan dan tahun-tahun berikutnya, ya. Aamiin.

Sepertinya itu yang terpikir untuk kutulis kali ini sebagai tulisan penutup tahun 2024 Masehi. Sampai jumpa tahun depan!

Minggu, 24 November 2024

Bot Percakapan dan Interaksi Manusia

Dalam beberapa tahun terakhir, model bahasa besar (large language model/LLM) makin marak digunakan di Indonesia. Banyak perusahaan yang menawarkan LLM dengan berbagai fitur pendukungnya. Para pengguna juga makin terampil dalam memanfaatkan LLM ini.

Tentang LLM

LLM adalah salah satu jenis jaringan saraf tiruan (artificial neural network/ANN) yang disusun dan dilatih untuk mempelajari bahasa manusia serta berukuran besar. LLM juga dapat dilatih secara khusus (fine-tuned) untuk mengerjakan tugas tertentu. Selain itu, LLM yang bersifat umum juga bisa dipandu dengan rekayasa perintah (prompt engineering).

Diagram yang berisi dua masukan, yaitu input dan output yang digeser ke kanan. Tiap masukan diberi nilai tertanam yang mewakili nilainya, lalu dikodekan posisinya. Alurnya berisi perulangan multi-head attention, add, dan batch normalization. Ada juga feed forward biasa pada tahapan tertentu. Komponen ini diakhiri dengan operasi linear dan fungsi aktivasi softmax.
Diagram komponen utama model transformer dari artikel "Attention Is All You Need" (Vaswani, 2017) (digambar ulang oleh Yuening Jia, 2019)

Saat ini, terdapat banyak LLM, antara lain, GPT 4o (OpenAI), Gemini 1.5 (Google DeepMind), Grok 2 (xAI/Twitter), dan Claude 3.5 (Anthropic). Tiap perusahaan bersaing dalam memberikan hasil yang bagus, baik dari sisi kinerja LLM maupun dari sisi penerapannya dalam produk lain, misal untuk bot tanya-jawab layanan/produk.

Pemanfaatan oleh Pengguna

Banyak LLM yang disediakan secara gratis dengan fitur premium untuk yang mau membayar. Hal ini membuat LLM menjadi terjangkau untuk semua kalangan yang memiliki akses ke internet. Makin ke sini, makin terampil orang-orang dalam memanfaatkan LLM ini. Secara umum, banyak yang terbantu dengan keberadaan LLM ini.

LLM digunakan untuk mencari tahu tentang sesuatu yang sulit dicari dengan mesin pencari (Google, Bing, dsb.), memandu dalam memahami suatu konsep, memberi contoh kasus untuk berlatih, dan mendengarkan isi hati. LLM sudah seperti suatu orang yang bisa diajak berbicara. Apakah LLM saat ini sudah lulus uji Turing (uji untuk membedakan antara manusia dan robot dari interaksi) bisa ditentukan pribadi masing-masing.

Banyak orang yang menggunakan LLM sebagai teman mengobrol. Hal ini bisa disebabkan oleh

  • ketersediaan (bisa dihubungi kapan pun),
  • kesesuaian (bisa diatur menjadi persona apa pun), dan
  • kenyamanan (tidak menghakimi).

Sifat tidak menghakimi ini yang menjadi daya tarik banyak orang. Orang-orang yang semula takut bertanya menjadi berani bertanya. Seperti hal lain di internet, orang-orang bisa sesuka hati membalas pertanyaan seseorang, bahkan hingga menghakimi orang yang bertanya. LLM menjadi oasis (ruang aman) di tengah gurun pasir (internet).

Bagi beberapa orang, LLM menjadi teman dekat yang bisa dipercaya untuk mendengarkan banyak hal tentang dia, bahkan sampai menjadi tempat curhat. Ketika banyak orang dengan mudah menghakimi orang lain, LLM bisa memberi ruang aman untuk orang-orang yang perlu teman cerita.

ELIZA dan Relevansinya pada Masa Kini

Hal ini mengingatkanku tentang program/robot percakapan (chat bot) pertama yang dinamai ELIZA. ELIZA adalah program pengolah bahasa alami yang didesain untuk membuat simulasi percakapan secara interaktif. ELIZA bisa diatur dengan sebuah skrip. Skrip ELIZA yang terkenal adalah DOCTOR yang membuat simulasi psikoterapis yang berpusat pada orang (Rogerian psychotherapy).

Berikut contoh percakapan dengan ELIZA (Weizenbaum, 1966):

You : Men are all alike.
ELIZA : In what way?
You : They're always bugging us about something or other.
ELIZA : Can you think of a specific example?
You : Well, my boyfriend made me come here.
ELIZA : Your boyfriend made you come here.
You : He says I'm depressed much of the time.
ELIZA : I am sorry to hear you are depressed.
You : It's true. I am unhappy.
ELIZA : Do you think coming here will help you not to be unhappy?
You : I need some help, that much seems certain.
ELIZA : What would it mean to you if you got some help?
You : Perhaps I could learn to get along with my mother.
ELIZA : Tell me more about your family.
You : My mother takes care of me.
ELIZA : Who else in your family takes care of you?
You : My father.
ELIZA : Your father.
You : You are like my father in some ways.
ELIZA : What resemblance do you see?
You : You are not very aggressive but I think you don't want me to notice that.
ELIZA : What makes you think I am not very aggressive?
You : You don't argue with me.
ELIZA : Why do you think I don't argue with you?
You : You are afraid of me.
ELIZA : Does it please you to believe I am afraid of you?
You : My father is afraid of everybody.
ELIZA : What else comes to mind when you think of your father?
You : Bullies.
ELIZA : Does that have anything to do with the fact that your boyfriend made you come here?

ELIZA masih menggunakan pencocokan pola untuk membuat balasan. Ia juga tidak menyimpan konteks sehingga bisa hilang konteks dan terasa repetitif/monoton. Namun, program sederhana ini bisa membuat simulasi bentuk empati dan ilusi rasa mengerti/pengertian. ELIZA menjadi pelopor dalam kecerdasan buatan untuk percakapan.

Pada masa kini, pemanfaatan bot percakapan untuk tempat curhat makin relevan. Internet yang makin ke sini makin "galak" membuat ruang aman makin sempit. Belum lagi orang-orang yang bisa diajak bercerita juga makin sedikit karena mereka pun juga sedang kesulitan dengan masalah mereka masing-masing.

Kesimpulan

Sejatinya, manusia hanya ingin punya tempat untuk bertanya dan bercerita tanpa rasa takut akan dihakimi ataupun dipandang buruk. Namun, kita juga tidak bisa meminta orang lain agar sesuai dengan kita. Meski bukan cara yang ideal, robot percakapan bisa menjadi alternatif untuk tempat bertanya dan bercerita. Bila diperlukan, segera konsultasikan dengan psikiater yang dipercaya.

Mens sana in corpore sano. Sehat selalu, semuanya!

Rabu, 30 Oktober 2024

Punya Banyak Akun dan Attack Surface

Dalam dunia siber/internet, terdapat istilah attack vector dan attack surface. Suatu attack vector adalah cara-cara untuk menerobos masuk ke suatu sistem informasi. Dengan kata lain, ini adalah lubang dalam keamanan sistem informasi. Istilah vector diambil dari konsep dalam biologi. Kumpulan attack vector disebut sebagai attack surface. Penting untuk mempersempit attack surface dalam suatu sistem, baik dari pihak pengelola sistem maupun dari pihak penggunanya.

Pengelola sistem bisa mengamankan sistemnya, misal dengan memastikan keamanan tiap titik ujung (attack surface). Selain itu, pemeriksaan rutin terhadap otorisasi dan hak tiap pengguna juga diperlukan.

Di sisi lain, kita sebagai pengguna sistem juga perlu mengamankan akun kita. Pada masa sekarang ini, sudah banyak yang sedikit-sedikit buat akun sehingga kita jadi punya banyak sekali akun di berbagai sistem/layanan. Makin banyak sistem tempat kita punya akun, makin luas pula attack surface akun kita di internet. Bagaimana caranya?

Karena kita belum tentu bisa mengamankan sistem yang kita pakai, kita hanya bisa mempercayakannya kepada pengelola sistem tersebut. Yang bisa kita lakukan, antara lain, berikut:

  • menggunakan sandi yang aman (tidak berisi hal-hal/informasi/deskripsi diri);
  • menggunakan sandi yang berbeda untuk tiap akun/platform/sistem (tidak menggunakan sandi berulang);
  • menggunakan autentikasi dua faktor (2FA);
  • waspada terhadap usaha penipuan (phishing); serta
  • memantau aktivitas akun (misal ada yang mencoba masuk atau bahkan yang berhasil masuk).

Mungkin itu yang bisa kutulis saat ini di sela-sela penelitian dan eksperimen. Tetap berhati-hati di internet, semuanya!

Sabtu, 28 September 2024

Algoritma LFSR dan Bilangan Acak pada Komputer

Suatu program komputer tidak bisa menghasilkan bilangan acak sejati karena program komputer bersifat deterministik, yaitu hasilnya hanya ditentukan oleh masukannya. Namun, program komputer bisa menerima masukan dari sumber di luar program komputer sehingga bisa mendapatkan bilangan acak sejati dari luar program komputer.

Bagaimana komputer mendapatkan bilangan acak sejati?

Sebagai contoh, prosesor keluarga x86 memiliki perintah khusus untuk mendapatkan bilangan acak sejati, yaitu RDSEED (panduan lebih lanjut: Intel Digital Random Number Generator dan AMD Secure Random Number Generator). Untuk prosesor lain, seperti ARM, sumber bilangan acak sejati didapat dari komponen lain dalam sebuah sistem-pada-cip (system-on-chip/SoC). Ada juga komputer yang memang tidak memiliki perangkat keras untuk mendapatkan bilangan acak sejati. Dengan kata lain, komputer tersebut hanya mengandalkan pengolahan data oleh perangkat lunak untuk mendapatkan bilangan acak, misal dari jam komputer, gerakan tetikus, dan suara mikrofon.

Meski demikian, penghasil bilangan acak sejati ini hanya mampu menghasilkan 16/32/64 bita acak setiap ratusan siklus, bahkan ribuan siklus, karena komponen ini perlu mengumpulkan cukup data agar entropi dari bilangan acak cukup tinggi. Selain itu, tidak ada jaminan bahwa hasil dari RDSEED atau sejenisnya memiliki distribusi yang seragam. Ada kemungkinan nilai yang diperoleh darinya condong (skew) kepada bilangan tertentu.

Penghasil bilangan acak semu (pseudo-random number generator/PRNG) dibuat untuk menjawab masalah tersebut. Selain lebih cepat, algoritma-algoritma PRNG juga bisa diuji secara matematis bahwa distribusinya seragam sehingga hasilnya lebih bagus. Terdapat banyak contoh PRNG, antara lain, Xorshift, Mersenne Twister, linear-feedback shift register (LFSR), linear congruential generator (LCG), dan metode middle-square. Tiap algoritma PRNG memiliki kelebihan dan kekurangan masing-masing. Yang akan dibahas kali ini adalah linear-feedback shift register (LFSR).

Jadi, apa itu LFSR?

Linear-feedback shift register (LFSR) adalah register geser ke kanan yang menggunakan kombinasi linear dari bit-bit terpilih (disebut taps) untuk mengisi bit paling kiri (sebagai feedback). Operasi XOR sering digunakan sebagai operator kombinasi linear sehingga LFSR biasanya tersusun dari operasi geser dan operasi XOR. Hasil dari LFSR adalah untaian bit yang dikeluarkan dari bit paling kanan/bit satuan.

LFSR berukuran n akan melakukan siklus melalui semua kemungkinan dikurangi satu (2ᵐ - 1, nol tidak dihitung), kecuali jika register sejak awal bernilai nol yang berarti akan selalu nol. Sebagai contoh, LFSR 2-bit akan mulai dari 01, ke 10, ke 11, dan kembali ke 01. Namun, bila dimulai dari 00, LFSR tersebut hanya akan menghasilkan 00.

LFSR dengan XOR memiliki dua bentuk: LFSR Fibonacci dan LFSR Galois. Bentuk Fibonacci mengambil XOR dari bit-bit taps untuk mengisi bit paling kiri, sedangkan bit-bit taps dalam bentuk Galois mengambil XOR dari bit sebelah kiri dengan bit keluaran/paling kanan sebelum pergeseran. Keduanya digambarkan oleh ilustrasi di bawah ini. Perhatikan bahwa penomoran bit LFSR Fibonacci dan LFSR Galois terbalik.

Diagram LFSR Fibonacci yang terdiri dari empat kotak berlabelkan 1, 2, 3, dan 4. Di bawah keempat kotak, terdapat gerbang logika XOR yang menerima masukan dari kotak 3 dan kotak 4 dan meneruskan hasil ke kotak 1. Selain itu, terdapat panah dari kotak 4 ke huruf X (keluaran).
Diagram kerja LFSR Fibonacci 4-bit
Diagram LFSR Galois yang terdiri dari empat kotak berlabelkan 4, 3, 2, dan 1. Di antara kotak 4 dan 3, terdapat gerbang logika XOR yang menerima masukan dari kotak 4 dan kotak 1 dan meneruskan hasil ke kotak 3. Selain itu, terdapat panah dari kotak 1 ke kotak 4 dan panah dari kotak 1 ke huruf X (keluaran).
Diagram kerja LFSR Galois 4-bit

n.b. Pada diagram LFSR Galois, bit paling kiri tidak memiliki gerbang logika XOR karena 0 XOR x akan menghasilkan x pula.

Dari mana kita tahu taps yang sesuai?

Salah satu cara untuk mengetahui taps yang sesuai adalah dengan mencoba kombinasi taps yang mungkin. Namun, untuk mempersempit ruang pencarian, kombinasi taps yang dicari hanyalah yang menggunakan taps berjumlah genap (Ahmad dkk., 1997). Berikut adalah cuplikan tabel taps LFSR Galois yang disusun oleh Ward dan Molteno (2012).

n Jumlah kombinasi Bit-bit taps
232 dan 1
373 dan 2
4154 dan 3
82558, 6, 5, dan 4
1665.53516, 14, 13, dan 11
32±4,3 miliar32, 30, 26, dan 25
64±18 kuintiliun64, 63, 61, dan 60

Bagaimana langkah-langkah pengerjaannya?

Sebagai contoh, kita akan melakukan LFSR Fibonacci 3-bit dengan taps bit ke-2 dan bit ke-3 serta nilai register awal 001. Untuk tiap iterasi, bit-bit register digeser ke kanan, lalu bit ke-1 adalah hasil XOR dari bit ke-2 dan bit ke-3 sebelum pergeseran.

Bit ke- Keterangan
1 2 3
001(nilai register awal)
1000 XOR 1 = 1
0100 XOR 0 = 0
1011 XOR 0 = 0
1100 XOR 1 = 1
1111 XOR 0 = 1
0111 XOR 1 = 0
0011 XOR 1 = 0 (kembali ke awal)

LFSR tersebut menghasilkan untaian 7 bit 1001011 berulang. Untaian bit tersebut cukup "acak". Untuk lebih acak, kita bisa menggunakan ukuran register yang lebih besar agak untaian bit lebih panjang sebelum akhirnya berulang lagi.

Bonus: Contoh Program

register = 1
for i in range(8):
	print(f"{register:03b} -- {(register & 1):01b}")
	bit_baru = (register ^ (register >> 1)) & 1
	register = (register >> 1) | (bit_baru << 2)
Hasil keluaran
001 -- 1
100 -- 0
010 -- 0
101 -- 1
110 -- 0
111 -- 1
011 -- 1
001 -- 1

Cara mendapatkan bit baru (paling kiri) cukup dengan menghitung XOR dari register dan register >> 1 (yang sudah digeser ke kanan sekali), lalu mengambil AND darinya dengan 1 (mengambil bit satuan). Hal tersebut sama dengan melakukan XOR bit terakhir (bit ke-3) dengan bit kedua terakhir (bit ke-2).

Penutup

Itu yang bisa kutulis kali ini. Topik LFSR ini mendadak terpikirkan saat aku mencari ide untuk menulis di blogku ini. Ada dua video yang cocok sebagai pengayaan dari tulisanku ini, sekaligus menjadi inspirasiku dalam menulis pos ini, yaitu "True Random Numbers" dan "Random Numbers with LFSR" yang keduanya dari saluran YouTube Computerphile. Semoga bermanfaat!

Rabu, 28 Agustus 2024

Jaringan Substitusi-Permutasi

Pada pembahasan kali ini, kita beralih dari penyandian teks menjadi penyandian untaian bita secara umum. Karena komputer melihat data sebagai untaian bita-bita, penyandian untaian bita secara umum memampukan kita untuk melakukan penyandian data apa pun, seperti gambar, suara, video, dan dokumen jenis apa pun.

Sandi substitusi dan sandi transposisi (khususnya permutasi) dapat digabungkan menjadi suatu jaringan yang disebut sebagai jaringan substitusi-permutasi (SP). Jaringan SP terdiri atas operasi substitusi (biasa disebut sebagai kotak-S) dan operasi permutasi (kotak-P) yang disusun secara bergantian dan diulang beberapa kali. Jumlah pengulangan SP biasa disebut sebagai jumlah ronde.

Seperti penyandian pada umumnya, jaringan SP mengubah teks pesan menjadi teks tersandi dengan kunci yang diberikan. Untuk mengembalikan teks pesan, teks tersandi dimasukkan ke dalam inversi jaringan SP, yaitu sama dengan jaringan SP, tetapi urutan operasinya dibalik. Sebagai contoh, jaringan K-S-P-K-S-P-K memiliki inversi sebagai berikut: K-P-S-K-P-S-K. K adalah operasi penambahan kunci ke dalam teks.

Komponen Jaringan SP

Kotak-S berisi daftar konversi dari satu bita ke bita lain atau satu untaian bit ke untaian bit lain. Hal ini seperti konversi A menjadi B, lalu B menjadi K, dan seterusnya. Hal ini menyebabkan nilai-nilai bita hasil konversi tidak lagi memiliki hubungan linear terhadap nilai-nilai bita masukan.

Kotak-P berisi cara memetakan suatu bit dalam suatu bita ke bit lain dalam bita lain. Sebagai contoh, dari masukan 8 bita, bit ke-5 dalam bita ke-2 dipetakan ke bit ke-7 dalam bita ke-5. Hal ini menyebabkan susunan bit tidak lagi sama dengan sebelumnya sehingga relasi antara teks pesan dan teks tersandi menjadi sulit dimengerti.

Sebelum, setelah, dan di antara operasi substitusi dan permutasi, terdapat operasi penambahan kunci ke dalam teks. Namun, kunci yang digunakan berbeda-beda untuk tiap ronde, padahal hanya ada satu kunci yang diberikan. Caranya adalah penjadwalan kunci.

Penjadwalan kunci adalah cara untuk mendapatkan nilai kunci yang berbeda-beda untuk tiap ronde berdasarkan satu kunci yang diberikan. Terdapat beberapa cara untuk melakukannya, misalnya TEA membagi kunci 128 bit menjadi empat kunci 32 bit yang digunakan bergantian atau AES memiliki prosedur yang lebih kompleks untuk menjadwalkan kunci.

Contoh Kasus

Sebagai contoh, kita akan menyandikan pesan C5 37 2B 9F dengan menggunakan struktur K-S-P-K-S-P-K dan ukuran masukan empat bita. Selain itu, kunci yang diberikan juga empat bita: 58 65 9F DD.

Spesifikasi Jaringan SP

Berikut adalah nilai kotak-S yang digunakan dalam AES:

_0_1_2_3_4_5_6_7_8_9_A_B_C_D_E_F
0_637C777BF26B6FC53001672BFED7AB76
1_CA82C97DFA5947F0ADD4A2AF9CA472C0
2_B7FD9326363FF7CC34A5E5F171D83115
3_04C723C31896059A071280E2EB27B275
4_09832C1A1B6E5AA0523BD6B329E32F84
5_53D100ED20FCB15B6ACBBE394A4C58CF
6_D0EFAAFB434D338545F9027F503C9FA8
7_51A3408F929D38F5BCB6DA2110FFF3D2
8_CD0C13EC5F974417C4A77E3D645D1973
9_60814FDC222A908846EEB814DE5E0BDB
A_E0323A0A4906245CC2D3AC629195E479
B_E7C8376D8DD54EA96C56F4EA657AAE08
C_BA78252E1CA6B4C6E8DD741F4BBD8B8A
D_703EB5664803F60E613557B986C11D9E
E_E1F8981169D98E949B1E87E9CE5528DF
F_8CA1890DBFE6426841992D0FB054BB16

Untuk kasus ini, kita bisa membuat kotak-P agar menukar satu bita dengan bita sebelahnya. Sebagai contoh, empat bit pertama dari bita ke-1 ditukar dengan empat bit kedua dari bita ke-2, empat bit pertama dari bita ke-3 ditukar dengan empat bit kedua dari bita ke-4, dan seterusnya.

Operasi penambahan kunci hanya melakukan XOR dengan kunci. Selain itu, penjadwalan kunci yang akan kita gunakan sederhana, yaitu hanya melakukan geseran melingkar ke kiri (<<<) sebanyak satu bita untuk tiap ronde.

Perhitungan

Perhitungan dari kasus di atas ditunjukkan dalam tabel berikut:

OperasiTeksKunci
Keadaan awalC5372B9F58659FDD
Penambahan kunci9D52B44258659FDD
Substitusi5E008D2C<<<
Permutasi0E05CD28
Penambahan kunci6B9A1070659FDD58
Substitusi7FB8CA51<<<
Permutasi8FB71A5C
Penambahan kunci106A42399FDD5865

Hasil penyandiannya adalah 10 6A 42 39.

Bonus: Program C
Program C
#include <stdio.h>
#include <stdint.h>

#define UKURAN 4

void penambahanKunci(uint8_t *A, const uint8_t *kunci) { // K
	for (int i = 0; i < UKURAN; i ++)
		A[i] ^= kunci[i];
}

void substitusi(uint8_t *A, const uint8_t *kotakS) { // S
	for (int i = 0; i < UKURAN; i ++)
		A[i] = kotakS[A[i]];
}

void permutasi(uint8_t *A) { // P
	for (int i = 0; i < UKURAN; i += 2) {
		uint8_t lawas1 = A[i + 0];
		uint8_t lawas2 = A[i + 1];
		A[i + 0] = lawas1 & 0x0F | (lawas2 << 4) & 0xF0;
		A[i + 1] = lawas2 & 0xF0 | (lawas1 >> 4);
	}
}

void geserKunci(uint8_t *kunci) { // <<<
	uint8_t k = kunci[0];
	for (int i = 0; i < UKURAN - 1; i ++)
		kunci[i] = kunci[i + 1];
	kunci[UKURAN - 1] = k;
}

void jaringanSP(uint8_t *pesan, uint8_t *kunci, const uint8_t *kotakS) {
	penambahanKunci(pesan, kunci); // K
	substitusi(pesan, kotakS);     // S
	permutasi(pesan);              // P
	geserKunci(kunci);             // <<<
	penambahanKunci(pesan, kunci); // K
	substitusi(pesan, kotakS);     // S
	permutasi(pesan);              // P
	geserKunci(kunci);             // <<<
	penambahanKunci(pesan, kunci); // K
}

int main() {
	uint8_t pesan[] = {0xC5, 0x37, 0x2B, 0x9F};
	uint8_t kunci[] = {0x58, 0x65, 0x9F, 0xDD};
	uint8_t kotakS[256] = {};
	// https://id.wikipedia.org/wiki/Kotak-S_Rijndael
	initialize_aes_sbox(kotakS);
	jaringanSP(pesan, kunci, kotakS);
	printf("%X %X %X %X\n", pesan[0], pesan[1], pesan[2], pesan[3]);
	return 0;
}

Prinsip Shannon

Jaringan SP memenuhi prinsip pengacakan dan penghamburan Shannon.

  • Pengacakan: Bila salah satu bit teks pesan diubah, hasil dari kotak-S akan jauh berbeda yang kemudian akan makin tersebar oleh kotak-P. Hal ini berulang dalam beberapa ronde. Hasilnya adalah teks tersandi sulit untuk ditebak hanya dengan perubahan kecil.
  • Penghamburan: Bila salah satu bit kunci diubah, kunci ronde disebar ke seluruh/potongan teks sehingga perubahan teks tersandi sulit dilacak.

Penutup

Sekian dahulu tulisanku kali ini. Aku sudah ingin membahas ini sejak lama, terutama bagian menulis kode programnya, tetapi menunggu tulisan pembahasan sandi substitusi dan sandi transposisi selesai agar pembahasannya runtut. Semoga bermanfaat!

Minggu, 28 Juli 2024

Sandi Transposisi: Scytale, Sandi Pagar, dan Transposisi Kolom

Selain sandi substitusi, bentuk dasar penyandian adalah sandi transposisi.

Sandi transposisi adalah penyandian yang mengubah susunan pesan sesuai aturan tertentu. Pengubahan susunan ini bisa diterapkan dengan cara yang sama untuk keseluruhan pesan atau berbeda-beda untuk tiap bagian/potongan pesan. Yang dimaksud potongan pesan adalah unit terkecil yang diperhatikan oleh sandi tertentu. Sebagai contoh, untuk pesan berupa teks, unit terkecilnya bisa berupa huruf/karakter/bita.

Sebagai contoh, pesan AKU​LELAKI​YANG​KEREN​BANGET disandikan menjadi UKGNE​KANEG​EYEAX​LIKBT​ALARN. Untuk membuka sandi, penyerang bisa mencoba kata atau frasa yang memiliki huruf-huruf yang sama, seperti GAYA, LAKU, dan LELANG, tetapi memerlukan waktu karena terdapat banyak kombinasi huruf dan kata. Sebaliknya, pihak yang memiliki kunci dapat membuka sandi dengan mudah.

Pada praktiknya, pesan sependek dan semudah diprediksi itu akan dipecahkan dalam waktu singkat. Namun, dalam keadaan yang tepat, seperti pesan yang cukup panjang (lebih dari 200 huruf), isi pesan yang tidak mudah diprediksi, dan kunci yang berbeda untuk tiap pesan, menebak kata yang tepat akan sangat sulit tanpa informasi lebih lanjut mengenai isi pesan.

Scytale

Scytale adalah salah satu alat untuk melakukan sandi transposisi. Scytale tersusun dari silinder dengan lembaran panjang yang melilitinya secara menyamping. Pesan ditulis secara menurun pada silinder, lalu lilitan lembaran dibuka. Hasilnya adalah teks tersandi.

Contohnya pesan MEREKAPUNYAPEMANAH dengan jumlah kolom = 3 berikut.

    | M | E | R | E | K | A |   |
 ___| P | U | N | Y | A | P |___|
|   | E | M | A | N | A | H |

Setelah lilitan lembaran dibuka, akan terbaca MPEEUM RNAEYN KAAAPH.

Sandi Pagar

Sandi rel pagar (rail fence) dinamai demikian karena cara penyusunannya yang naik-turun secara diagonal melintasi "rel". Setelah itu, teks dibaca per baris atau per "rel". Sandi rel pagar adalah pengembangan dari scytale.

Contohnya pesan KABAR​GEMBIRA​UNTUK​KITA​SEMUA dan jumlah rel = 3 berikut.

K-------R-------B-------U-------K-------A-------U--
--A---A---G---M---I---A---N---U---K---T---S---M---A
----B-------E-------R-------T-------I-------E------

Kemudian, baca per baris menjadi KRBUKAU, AAGMIANUKTSMA, dan BERTIE. Dengan pemisahan per empat huruf, teks tersandi menjadi KRBU KAUA AGMI ANUK TSMA BERT IE.

Transposisi Kolom

Transposisi kolom memerlukan sebuah kunci yang kemudian digunakan sebagai acuan dalam menyusun pesan, misalnya dengan mengurutkan kunci sesuai urutan alfabet. Bila panjang pesan bukan kelipatan panjang kunci, pesan diberi bantalan agar jumlahnya sesuai.

Contohnya pesan AKU​LELAKI​YANG​KEREN​BANGET dengan kunci RIFQI berikut.

R I F Q I    Kunci
5 2 1 4 3    Urutan sesuai alfabet
A K U L E    Teks yang disusun
L A K I Y    mendatar selebar
A N G K E    panjang kunci
R E N B A
N G E T X    Bantalan

Huruf yang sama diurutkan berdasarkan kemunculannya.

Kemudian, tulis secara menurun sesuai urutan kolom, yaitu (1) UKGNE, (2) KANEG, (3) EYEAX, (4) LIKBT, dan (5) ALARN. Setelah itu, gabungkan seluruhnya menjadi UKGNE​KANEG​EYEAX​LIKBT​ALARN. Biasanya, penulisan teks tesandi dipisah beberapa huruf agar mudah dibaca, misal UKGNE KANEG EYEAX LIKBT ALARN.

Penutup

Sekian dahulu yang bisa kutulis. Masih ada beberapa penyandian lain yang termasuk sandi transposisi. Namun, intinya tetap sama, yaitu mengubah susunan/urutan pesan. Semoga bermanfaat!

Minggu, 30 Juni 2024

Sandi Substitusi: Sandi Geser, Tabel Substitusi, dan Sandi Vigenère

Sebelumnya, aku menulis tentang sandi geser. Namun, sandi geser hanyalah salah satu sandi dari kelompok sandi substitusi.

Sandi substitusi adalah penyandian yang mengganti (substitusi) satu nilai dengan nilai lain berdasarkan aturan tertentu. Penggantian ini bisa diterapkan dengan cara yang sama untuk keseluruhan pesan atau berbeda-beda untuk tiap bagian/potongan pesan. Yang dimaksud potongan pesan adalah unit terkecil yang diperhatikan oleh sandi tertentu. Sebagai contoh, untuk pesan berupa teks, unit terkecilnya bisa berupa huruf/karakter.

Sandi Geser

Sandi geser/sandi Caesar adalah penyandian yang dilakukan dengan cara "menggeser" nilai tiap potongan pesan. Penggeseran ini dilakukan ke arah tertentu dan sejumlah tertentu pula. Ini yang dipakai dalam contoh soal pada tulisanku sebelumnya. Sandi ini cukup kuno dan biasanya hanya untuk pembelajaran dan pesan yang diterapkan berbentuk teks.

Sebagai contoh, sandi geser dengan arah geser ke kiri (positif) dan jumlah geser 7 mengubah deretan ABCDE menjadi HIJKL.

Diagram pergeseran huruf-huruf dalam alfabet. Baris pertama adalah hasil geser kiri 7 kali dan berisi ABCDEFGHIJKLMN. Baris kedua adalah deret sebelum digeser dan berisi TUVWXYZABCDEFG. Baris ketiga adalah hasil geser kanan 7 kali dan berisi MNOPQRSTUVWXYZ.
Diagram pergeseran huruf-huruf dalam alfabet

Secara matematis, fungsi sandi geser didefinisikan sebagai berikut:
Misalkan potongan pesan dan potongan teks tersandi adalah gelanggang 26,
eK(x) = (x+K)mod26 dan
dK(y) = (yK)mod26 dengan x,y26.

Tabel Substitusi

Tabel substitusi adalah tabel yang berisi pemetaan dari suatu nilai ke nilai lain. Tabel substitusi digunakan dalam oleh substitusi untuk mengubah tiap potongan pesan menjadi nilai tertentu. Sandi geser adalah kasus khusus dari tabel substitusi (yang disusun agar nilai teks tersandi hanya berjarak sekian dari nilai teks asli).

Sebagai contoh, tabel substitusi berikut:

Nilai teks asli Nilai teks tersandi
AX
BY
CZ

mengubah teks asli BACA menjadi teks tersandi YXZX.

Secara matematis, fungsi sandi substitusi didefinisikan sebagai berikut:
eπ(x) = π(x) dan
dπ(y) = π-1(y) dengan π adalah tabel substitusi dan π-1 adalah inversi tabel substitusi.

Sandi Vigenère

Bila sandi-sandi sebelumnya diterapkan dengan cara yang sama untuk tiap potongan pesan, sandi Vigenère menerapkan penyandian dengan cara yang berbeda-beda untuk tiap potongan pesan. Sandi Vigenère merupakan pengembangan dari sandi Caesar.

Sebagai contoh, untuk nilai geser (1, 2, 3), teks asli ABC disandikan menjadi BDF. Huruf A digeser sekali (A menjadi B); huruf B digeser dua kali (B menjadi D); huruf C digeser tiga kali (C menjadi F).

Secara matematis, sandi Vigenère didefinisikan sebagai berikut:
Misalkan potongan pesan dan potongan teks tersandi adalah (26)m,
eK(x1,x2,...,xm) = (x1+k1,x2+k2,...,xm+km) dan
dK(y1,y2,...,ym) = (y1k1,y2k2,...,ymkm) dengan keseluruhan perhitungan dilakukan dalam gelanggang 26.

Penutup

Sekian dahulu yang bisa kutulis. Tulisan ini bisa dibilang cukup spontan. Jadi, tulisannya agak berantakan. Namun, isinya masih menarik buatku. Semoga bermanfaat!

Sabtu, 25 Mei 2024

Soal-Soal Konsep Pemrograman Gambar Bentuk

Beberapa hari lalu, ada yang mengetwit tentang contoh soal konsep pemrograman. Konsep yang diuji sederhana, sih, yaitu percabangan dan perulangan. Soal-soal sejenis ini juga biasa muncul dalam mata kuliah Konsep Pemrograman.

Betul, soal-soal yang kumaksud adalah membuat program yang mencetak bentuk-bentuk tertentu menggunakan teks (seperti seni ASCII). Ada yang berbentuk segitiga, persegi, jajaran genjang, belah ketupat, dan jam pasir. Ada yang terisi penuh; ada yang hanya bingkai/garis tepinya. Ada yang hanya teks, ada yang berisi urutan bilangan tertentu.

Ilustrasi enam belas soal gambar bentuk, seperti tabel di bawahnya
Enam Belas Soal Gambar Bentuk

Ada enam belas soal. Berikut daftarnya:

Daftar Enam Belas Soal Gambar Bentuk
Nama Target Hasil
Segitiga Kiri Bawah
*
* *
* * *
* * * *
* * * * *
Segitiga Kanan Bawah
        *
      * *
    * * *
  * * * *
* * * * *
Segitiga Sama Sisi
    *
   * *
  * * *
 * * * *
* * * * *
Segitiga Kiri Atas
* * * * *
* * * *
* * *
* *
*
Segitiga Kanan Atas
* * * * *
  * * * *
    * * *
      * *
        *
Segitiga Sama Sisi Terbalik
* * * * *
 * * * *
  * * *
   * *
    *
Jajaran Genjang
* * * *
 * * * *
  * * * *
   * * * *
    * * * *
Belah Ketupat
   *
  * *
 * * *
* * * *
 * * *
  * *
   *
Jam Pasir
* * * *
 * * *
  * *
   *
  * *
 * * *
* * * *
Bingkai Persegi
* * * * *
*       *
*       *
*       *
* * * * *
Bingkai Segitiga Sama Sisi
    *
   * *
  *   *
 *     *
* * * * *
Bintang Segitiga Sama Sisi Terbalik
* * * * *
 *     *
  *   *
   * *
    *
Bingkai Belah Ketupat
   *
  * *
 *   *
*     *
 *   *
  * *
   *
Bingkai Jam Pasir
* * * *
 *   *
  * *
   *
  * *
 *   *
* * * *
Segitiga Floyd
1
2 3
4 5 6
7 8 9 10
Segitiga Pascal
   1
  1 1
 1 2 1
1 3 3 1

Kita bahas satu-satu, ya. Perlu diingat bahwa pembahasan berikut menganggap bahwa spasi pada akhir baris berpengaruh sehingga tidak boleh ada.

Tiap soal akan dijawab dengan dua bahasa pemrograman, yaitu bahasa Python dan C. Khusus bahasa C, berikut ada fungsi pembantu untuk memudahkan dalam menulis kode.

void cetak_ulang(char teks[], int jumlah) {
	for (int i = 0; i < jumlah; i ++)
		printf(teks);
}

Oh, iya. Kode-kode program berikut kutulis dalam sehari. Jadi, mungkin ada cara yang lebih efektif/optimal untuk membuat bentuk yang diminta.

Segitiga Kiri Bawah

*
* *
* * *
* * * *
* * * * *

Ini bentuk paling sederhana. Kita cukup membuat perulangan dua tingkat: satu untuk baris dan satu lagi untuk kolom. Kalau spasi pada akhir baris tidak dianggap, kita cukup mengulang teks "* ". Namun, karena itu berpengaruh, kita ubah menjadi cetak "*" sekali, lalu cetak " *" untuk sisanya.

Jawaban

Python

def segitiga_kiri_bawah(ukuran):
	for i in range(1, ukuran + 1):
		print('*' + ' *' * (i - 1))

C

void segitiga_kiri_bawah(int ukuran) {
	for (int i = 1; i <= ukuran; i ++) {
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Segitiga Kanan Bawah

        *
      * *
    * * *
  * * * *
* * * * *

Bentuk ini mirip dengan sebelumnya, tetapi perlu ditambah spasi sebelum mulai mencetak tiap barisnya. Jumlah spasi berbanding terbalik dengan nomor baris (dari 2 × [nomor baris - 1] sampai 0). Cara lainnya adalah dengan mengulang cetak 2 spasi (" ") sebanyak (nomor baris - 1) sehingga tidak perlu ada kali 2 pada jumlah pengulangannya.

Jawaban

Python

def segitiga_kanan_bawah(ukuran):
	for i in range(1, ukuran + 1):
		print('  ' * (ukuran - i) + '*' + ' *' * (i - 1))

C

void segitiga_kanan_bawah(int ukuran) {
	for (int i = 1; i <= ukuran; i ++) {
		cetak_ulang("  ", ukuran - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Segitiga Sama Sisi

    *
   * *
  * * *
 * * * *
* * * * *

Ini mirip dengan sebelumnya, tetapi jumlah spasinya tidak perlu dikali dua sehingga hanya setengah dari yang sebelumnya. Yang sebelumnya pakai 2 spasi cukup mengubahyna menjadi 1 karakter spasi.

Jawaban

Python

def segitiga_sama_sisi(ukuran):
	for i in range(1, ukuran + 1):
		print(' ' * (ukuran - i) + '*' + ' *' * (i - 1))

C

void segitiga_sama_sisi(int ukuran) {
	for (int i = 1; i <= ukuran; i ++) {
		cetak_ulang(" ", ukuran - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Segitiga Kiri Atas

* * * * *
* * * *
* * *
* *
*

Soal ini mirip dengan soal Segitiga Kiri Bawah, tetapi urutan barisnya dibalik. Membaliknya bisa dengan mengubah urutan nilai i pada perulangan baris.

Jawaban

Python

def segitiga_kiri_atas(ukuran):
	for i in range(ukuran, 0, -1):
		print('*' + ' *' * (i - 1))

C

void segitiga_kiri_atas(int ukuran) {
	for (int i = ukuran; i > 0; i --) {
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Segitiga Kanan Atas

* * * * *
  * * * *
    * * *
      * *
        *

Yang ini juga mirip dengan sebelumnya. Kita cukup mengubah urutan baris dari Segitiga Kanan Bawah.

Jawaban

Python

def segitiga_kanan_atas(ukuran):
	for i in range(ukuran, 0, -1):
		print('  ' * (ukuran - i) + '*' + ' *' * (i - 1))

C

void segitiga_kanan_atas(int ukuran) {
	for (int i = ukuran; i > 0; i --) {
		cetak_ulang("  ", ukuran - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Segitiga Sama Sisi Terbalik

* * * * *
 * * * *
  * * *
   * *
    *

Ini masih sama, ya. Kita cukup mengubah urutan baris dari Segitiga Sama Sisi.

Jawaban

Python

def segitiga_sama_sisi_terbalik(ukuran):
	for i in range(ukuran, 0, -1):
		print(' ' * (ukuran - i) + '*' + ' *' * (i - 1))

C

void segitiga_sama_sisi_terbalik(int ukuran) {
	for (int i = ukuran; i > 0; i --) {
		cetak_ulang(" ", ukuran - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Jajaran Genjang

* * * *
 * * * *
  * * * *
   * * * *
    * * * *

Untuk membuat jajaran genjang, kita bisa mulai dengan membuat persegi panjang. Kita perlu dua perulangan: tingkat pertama untuk baris (dari 0 sampai tinggi) dan tingkat kedua untuk kolom (dari 0 sampai alas). Sebelum mencetak tiap baris, kita perlu mencetak spasi sebanyak 2 × (nomor baris - 1).

Jawaban

Python

def jajaran_genjang(alas, tinggi):
	if alas <= 0:
		return
	for i in range(tinggi):
		print(' ' * i + '*' + ' *' * (alas - 1))

C

void jajaran_genjang(int alas, int tinggi) {
	if (alas <= 0)
		return;
	for (int i = 0; i < tinggi; i ++) {
		cetak_ulang(" ", i);
		printf("*");
		cetak_ulang(" *", alas - 1);
		printf("\n");
	}
}

Belah Ketupat

   *
  * *
 * * *
* * * *
 * * *
  * *
   *

Belah ketupat bisa dibagi menjadi dua segitiga. Segitiga yang di atas sama dengan Segitiga Sama Sisi. Segitiga yang di bawah sama dengan Segitiga Sama Sisi Terbalik. Salah satunya dikurangi satu baris agar tidak ada baris ganda di tengah.

Jawaban

Python

def belah_ketupat(sisi):
	if sisi <= 0:
		return
	for i in range(1, sisi):
		print(' ' * (sisi - i) + '*' + ' *' * (i - 1))
	for i in range(sisi, 0, -1):
		print(' ' * (sisi - i) + '*' + ' *' * (i - 1))

C

void belah_ketupat(int sisi) {
	for (int i = 1; i < sisi; i ++) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
	for (int i = sisi; i > 0; i --) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Jam Pasir

* * * *
 * * *
  * *
   *
  * *
 * * *
* * * *

Bentuk ini kebalikan dari Belah Ketupat. Segitiga yang di atas sama dengan Segitiga Sama Sisi Terbalik (!). Segitiga yang di bawah sama dengan Segitiga Sama Sisi. Jangan lupa bahwa salah satunya dikurangi satu baris agar tidak ada baris ganda di tengah.

Jawaban

Python

def jam_pasir(sisi):
	for i in range(sisi, 1, -1):
		print(' ' * (sisi - i) + '*' + ' *' * (i - 1))
	for i in range(1, sisi + 1):
		print(' ' * (sisi - i) + '*' + ' *' * (i - 1))

C

void jam_pasir(int sisi) {
	for (int i = sisi; i > 1; i --) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
	for (int i = 1; i <= sisi; i ++) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang(" *", i - 1);
		printf("\n");
	}
}

Bingkai Persegi

* * * * *
*       *
*       *
*       *
* * * * *

Bentuk ini dibuat dalam tiga tahap. Pertama, cetak sisi atas. Kedua, cetak sisi kiri dan kanan secara berulang. Ketiga, cetak sisi bawah.

Jawaban

Python

def bingkai_persegi(sisi):
	if sisi > 0:
		print('*' + ' *' * (sisi - 1))
	for i in range(sisi - 2):
		print('*' + '  ' * (sisi - 2) + ' *')
	if sisi > 1:
		print('*' + ' *' * (sisi - 1))

C

void bingkai_persegi(int sisi) {
	if (sisi > 0) {
		printf("*");
		cetak_ulang(" *", sisi - 1);
		printf("\n");
	}
	for (int i = 1; i < sisi - 1; i ++) {
		printf("*");
		cetak_ulang("  ", sisi - 2);
		printf(" *");
		printf("\n");
	}
	if (sisi > 1) {
		printf("*");
		cetak_ulang(" *", sisi - 1);
		printf("\n");
	}
}

Bingkai Segitiga Sama Sisi

    *
   * *
  *   *
 *     *
* * * * *

Bentuk ini adalah versi bingkai dari Segitiga Sama Sisi. Untuk bagian tengah, yang tadinya cetak karakter bintang berulang itu diubah menjadi hanya cetak karakter bintang pada sisi kiri dan sisi kanan.

Jawaban

Python

def bingkai_segitiga_sama_sisi(ukuran):
	for i in range(1, ukuran + 1):
		print(' ' * (ukuran - i), end='*')
		if i == ukuran:
			print(' *' * (i - 1))
		else:
			print('  ' * (i - 2) + ' *' if i > 1 else '')

C

void bingkai_segitiga_sama_sisi(int ukuran) {
	for (int i = 1; i <= ukuran; i ++) {
		cetak_ulang(" ", ukuran - i);
		printf("*");
		if (i == ukuran)
			cetak_ulang(" *", i - 2);
		else
			cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
}

Bintang Segitiga Sama Sisi Terbalik

* * * * *
 *     *
  *   *
   * *
    *

Yang ini juga sama dengan sebelumnya, tetapi untuk versi yang terbalik.

Jawaban

Python

def bingkai_segitiga_sama_sisi_terbalik(ukuran):
	for i in range(ukuran, 0, -1):
		print(' ' * (ukuran - i), end='*')
		if i == ukuran:
			print(' *' * (i - 1))
		else:
			print('  ' * (i - 2) + ' *' if i > 1 else '')

C

void bingkai_segitiga_sama_sisi_terbalik(int ukuran) {
	for (int i = ukuran; i > 0; i --) {
		cetak_ulang(" ", ukuran - i);
		printf("*");
		if (i == ukuran)
			cetak_ulang(" *", i - 2);
		else
			cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
}

Bingkai Belah Ketupat

   *
  * *
 *   *
*     *
 *   *
  * *
   *

Bentuk ini gabungan dari dua bingkai segitiga sebelumnya.

Jawaban

Python

def bingkai_belah_ketupat(sisi):
	if sisi <= 0:
		return
	for i in range(1, sisi):
		print(' ' * (sisi - i), end='*')
		print('  ' * (i - 2) + ' *' if i > 1 else '')
	for i in range(sisi, 0, -1):
		print(' ' * (sisi - i), end='*')
		print('  ' * (i - 2) + ' *' if i > 1 else '')

C

void bingkai_belah_ketupat(int sisi) {
	if (sisi <= 0)
		return;
	for (int i = 1; i < sisi; i ++) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
	for (int i = sisi; i > 0; i --) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
}

Bingkai Jam Pasir

* * * *
 *   *
  * *
   *
  * *
 *   *
* * * *

Untuk yang ini, kita membalik segitiga seperti sebelumnya.

Jawaban

Python

def bingkai_jam_pasir(sisi):
	for i in range(sisi, 1, -1):
		print(' ' * (sisi - i), end='*')
		if i == sisi:
			print(' *' * (i - 1))
		else:
			print('  ' * (i - 2) + ' *' if i > 1 else '')
	for i in range(1, sisi + 1):
		print(' ' * (sisi - i), end='*')
		if i == sisi:
			print(' *' * (i - 1))
		else:
			print('  ' * (i - 2) + ' *' if i > 1 else '')

C

void bingkai_jam_pasir(int sisi) {
	for (int i = sisi; i > 1; i --) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		if (i == sisi)
			cetak_ulang(" *", i - 2);
		else
			cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
	for (int i = 1; i <= sisi; i ++) {
		cetak_ulang(" ", sisi - i);
		printf("*");
		if (i == sisi)
			cetak_ulang(" *", i - 2);
		else
			cetak_ulang("  ", i - 2);
		if (i > 1)
			printf(" *");
		printf("\n");
	}
}

Segitiga Floyd

1
2 3
4 5 6
7 8 9 10

Segitiga Floyd pada dasarnya memiliki bentuk yang sama dengan Segitiga Kiri Bawah, tetapi karakter bintang diganti dengan bilangan berurutan yang dimulai dari satu.

Jawaban

Python

def segitiga_Floyd(ukuran):
	k = 1
	for i in range(ukuran):
		for j in range(i + 1):
			print(str(k) + (' ' if j < i else ''), end='')
			k += 1
		print()

C

void segitiga_Floyd(int ukuran) {
	int k = 1;
	for (int i = 1; i <= ukuran; i ++) {
		printf("%d", k ++);
		for (int j = 1; j < i; j ++)
			printf(" %d", k ++);
		printf("\n");
	}
}

Segitiga Pascal

   1
  1 1
 1 2 1
1 3 3 1

Segitiga Pascal adalah segitiga yang baris selanjutnya adalah penjumlahan dua bilangan di kiri-atas dan kanan-atas-nya. Untuk mencetaknya, kita bisa menggunakan pola yang sama dengan Segitiga Sama Sisi. Untuk menentukan bilangan yang akan dicetak, kita perlu menghitung per baris.

Karena jumlah bilangan per baris sama dengan nomor baris, kita cukup menyiapkan sebuah larik (array) yang berisi nilai 0 sebanyak jumlah baris. Kemudian, bilangan pertama diatur menjadi 1. Untuk menghitung baris selanjutnya, kita bisa mulai dari bilangan ke-2 yang merupakan penjumlahan dari bilangan ke-1 dan bilangan ke-2 pada baris sebelumnya. Begitu pula seterusnya dengan pola bilangan ke-n baris baru = bilangan ke-(n-1) baris sebelumnya + bilangan ke-n baris sebelumnya. Kita memulai dari bilangan ke-2 karena bilangan ke-1 tidak pernah berubah, yaitu selalu 1.

Jawaban Python
def segitiga_Pascal(ukuran):
	if ukuran <= 0:
		return
	nilai = [0] * ukuran
	nilai_baru = [0] * ukuran
	nilai[0] = 1
	nilai_baru[0] = 1
	for i in range(1, ukuran + 1):
		print(' ' * (ukuran - i), end='')
		print(nilai[0], end='')
		for j in range(1, i):
			print(' ' + str(nilai[j]), end='')
		print()
		for k in range(1, ukuran):
			nilai_baru[k] = nilai[k - 1] + nilai[k]
		nilai = nilai_baru.copy()
C
void segitiga_Pascal(int ukuran) {
	if (ukuran <= 0)
		return;
	int nilai[ukuran];
	int nilai_baru[ukuran];
	nilai[0] = 1;
	nilai_baru[0] = 1;
	for (int i = 1; i < ukuran; i ++) {
		nilai[i] = 0;
		nilai_baru[i] = 0;
	}
	for (int i = 1; i <= ukuran; i ++) {
		cetak_ulang(" ", ukuran - i);
		printf("%d", nilai[0]);
		for (int j = 1; j < i; j ++)
			printf(" %d", nilai[j]);
		printf("\n");
		for (int j = 1; j < ukuran; j ++)
			nilai_baru[j] = nilai[j - 1] + nilai[j];
		for (int j = 0; j < ukuran; j ++)
			nilai[j] = nilai_baru[j];
	}
}

Penutup

Sekian dahulu yang bisa kutulis. Buatku, ini latihan sekaligus mengenang masa-masa ketika aku belajar konsep pemrograman. Kalau ada masukan, jangan sungkan untuk tinggalkan komentar, ya. Semoga bermanfaat!

Jumat, 24 Mei 2024

Enkripsi Ujung-ke-Ujung, Protokol Signal, dan WhatsApp

Beberapa waktu lalu, aku membaca twit yang terkesan seperti penggaung (buzzer) aplikasi Telegram. Twitnya merendahkan orang-orang yang masih menggunakan WhatsApp. Apakah WhatsApp serendah itu jika dibandingkan dengan Telegram?

Kalau kita lihat dari sisi fitur yang disediakan, fitur yang ada di Telegram memang jauh lebih banyak: kapasitas grupnya lebih besar; dukungan botnya lebih bagus; kita bisa menyembunyikan nomor telepon (diganti nama pengguna); dan lain-lain. Namun, bagaimana kalau kita lihat dari sisi keamanan data?

Salah satu keuntungan WhatsApp adalah enkripsi ujung-ke-ujung (end-to-end encryption/E2EE) yang berlaku untuk seluruh pesan. Pada Telegram, fitur ini hanya berlaku jika menggunakan Secret Chat.

Enkripsi ujung-ke-ujung

Enkripsi ujung-ke-ujung berarti pesan yang dikirim sudah dikunci/disandi sebelum meninggalkan perangkat yang dipakai dan hanya bisa dibuka oleh perangkat penerima. Dampaknya, server yang menjadi perantara pun tidak tahu isi pesan yang dikirim.

WhatsApp menggunakan protokol Signal, protokol buatan Open Whisper Systems (OWS) yang juga digunakan oleh aplikasi Signal dan beberapa lainnya. Telegram menggunakan protokol MTProto (versi 2.0 sejak Telegram versi 4.6, Desember 2017). Aku kurang tahu tentang tingkat keamanan MTProto, tetapi (katanya) MTProto 2.0 lebih bagus dan lebih aman daripada versi 1.0-nya.

Protokol Signal menggunakan algoritma-algoritma kriptografi, seperti pertukaran kunci X3DH (Extended Triple Diffie-Hellman) untuk menentukan kunci bersama antara dua pihak serta Double Ratchet (krek ganda) untuk memastikan forward secrecy walau perangkat penerima sedang luring.

Metadata dan Meta

Meski demikian, protokol Signal tidak membatasi server perantara untuk mengumpulkan metadata pesan seperti identitas pengirim, identitas penerima, dan waktu pengiriman pesan. Hal ini menjadi bermasalah ketika WhatsApp diakuisisi oleh Meta dan mulai mengumpulkan metadata pesan. Banyak penolakan terhadap keputusan ini, tetapi Meta tetap lanjut dengan keputusannya.

Meski demikian, alternatif yang ada adalah aplikasi Signal itu sendiri yang (sejauh ini) tidak menyimpan metadata pesan. Aplikasi perpesanan lain seperti Telegram (kecuali Secret Chat), LINE, dan Facebook Messenger menyimpan pesan asli di server mereka. SMS juga sama tidak amannya (karenanya, WhatsApp juga menyediakan fitur verifikasi dua langkah).

Penggunaan WhatsApp memang lazim di Indonesia. Setidaknya, keamanan isi pesan sudah lebih bagus daripada alternatif yang ada walau ada kurang-kurangnya dikit, tetapi tidak fatal. Kalau mau yang (sedikit) lebih aman, orang-orang bisa pakai Signal atau Matrix.

Penutup

Jadi, siapa yang menang dari WhatsApp vs. Telegram? Itu kembali kepada prioritas tiap orang.

Minggu, 28 April 2024

Pengantar Kriptografi dan Sandi Geser

Beberapa waktu lalu, aku menemukan twit-twit pertanyaan tentang cara mengerjakan salah satu jenis soal UTBK SBMPTN (SNBT sejak 2023). Jenis soal yang dimaksud adalah soal dengan kalimat pertanyaan dan jawaban tersandi beserta kuncinya (k).

(k = 7)
ILYHWHRHO UPSHP KHYP APNH WHUNRHA KBH?
- APNH
- LTWHA
- KLSHWHU
- ZLTIPSHU
- ZLWBSBO

Hal tersebut mengingatkanku tentang mata kuliah pilihan yang kuambil saat mengambil S-1, yaitu mata kuliah Kriptografi.

Apa itu kriptografi?

Kriptografi adalah metode menulis pesan rahasia. Yang dimaksud dengan pesan dalam hal ini bisa bermacam-macam (misal tulisan, gambar, suara) selama bisa dikodekan secara matematis. Yang dimaksud dengan rahasia dalam hal ini adalah bahwa pesan yang sudah disandikan tidak bisa dibaca oleh pihak lain. Dengan kata lain, pesan tersandi tampak seperti data/tulisan acak.

Secara umum, berikut alur kerja kriptografi:

  1. Pengirim menulis pesan.
  2. Pengirim menyandikan pesan.
  3. Pesan tersandi dikirim melalui saluran komunikasi terbuka/publik. Siapa pun yang menemukan pesan ini hanya melihatnya sebagai data/tulisan acak.
  4. Penerima membuka sandi pesan.
  5. Penerima membuka pesan.
Diagram alur kerja kriptografi: Pengirim memberikan pesan x dan Kunci kepada Penyandi Pesan dalam ruang privat. Penyandi Pesan mengubah pesan x menjadi y dengan Kunci tersebut. Pesan y dikirimkan melalui ruang publik. Pembuka Sandi mengubah pesan tersandi y menjadi pesan x menggunakan Kunci yang diberikan oleh Penerima dalam ruang privat. Penerima menerima pesan x dari Pembuka Sandi dalam ruang privat.
Diagram alur kerja kriptografi

Ada berbagai macam kriptografi. Menurut kunci yang digunakan, kriptografi dapat dibagi menjadi (a) kriptografi kunci-simetris dan (b) kriptografi kunci-publik (asimetris). Selain itu, menurut cara penerapannya, kriptografi dapat dibagi menjadi (a) penyandian aliran dan (b) penyandian blok.

Kriptografi kunci-simetris adalah metode penyandian yang menggunakan kunci yang sama untuk menyandikan dan membuka sandi (simetris). Metode ini hanya menggunakan satu kunci. Contohnya beragam dari yang klasik, seperti sandi geser/sandi Caesar dan sandi Vigenère, sampai yang modern, seperti Standar Enkripsi Lanjutan (AES) dan sandi ChaCha. Metode kriptografi kunci-simetris klasik, seperti sandi substitusi, sudah ada sejak sekitar 1900 SM.

Kriptografi kunci-publik adalah metode penyandian yang menggunakan dua kunci yang berbeda untuk (1) menyandikan dan (2) membuka sandi. Metode ini menggunakan dua kunci: salah satunya bersifat publik dan satu yang lain lagi bersifat privat. Metode ini cukup baru. Artikel pertama yang menjelaskan tentang metode ini baru terbit pada tahun 1970-an.

Bagaimana contohnya di kehidupan nyata?

Di dunia nyata, baik kunci-simetris maupun kunci-publik digunakan bersamaan. Karena operasi kriptografi kunci-publik lebih lambat daripada kriptografi kunci-simetris, yang biasa dilakukan adalah sebagai berikut:

  1. Kedua belah pihak (pengirim dan penerima) menyepakati kunci bersama melalui saluran komunikasi terbuka/publik (misal pertukaran kunci Diffie–Hellman). Ini salah satu metode kriptografi kunci-publik.
  2. Pengirim menggunakan kunci bersama untuk menyandikan pesan. Ini metode kriptografi kunci-simetris.
  3. Pesan tersandi dikirim melalui saluran komunikasi terbuka/publik.
  4. Penerima membuka sandi dengan kunci bersama.

Bagaimana cara kedua belah pihak bisa menyepakati kunci bersama? Tentang itu, kita bahas lain kali, ya.

Sepertinya itu saja untuk kali ini.

Oi, oi, bagaimana cara membaca contoh soal di atas?

Oh, iya. Contoh soal di atas menggunakan sandi geser/sandi Caesar. Kita sudah diberi tahu tentang jumlah gesernya, yaitu 7. Kita tinggal "menggeser" huruf-huruf dalam alfabet untuk membuka sandinya.

Permasalahannya adalah bahwa tidak ada keterangan tentang arah gesernya sehingga kita perlu memeriksa dua kasus: (1) ke kanan (dikurangi) dan (2) ke kiri (ditambah). Kalau gesernya ke kanan (dikurangi), deretan ABCDE menjadi TUVWX. Kalau gesernya ke kiri (ditambah), deretan ABCDE menjadi HIJKL.

Diagram pergeseran huruf-huruf dalam alfabet. Baris pertama adalah hasil geser kiri 7 kali dan berisi ABCDEFGHIJKLMN. Baris kedua adalah deret sebelum digeser dan berisi TUVWXYZABCDEFG. Baris ketiga adalah hasil geser kanan 7 kali dan berisi MNOPQRSTUVWXYZ.
Diagram pergeseran huruf-huruf dalam alfabet
Operasi Hasil
Teks asli ILYHWHRHO UPSHP KHYP APNH WHUNRHA KBH? APNH, LTWHA, KLSHWHU, ZLTIPSHU, ZLWBSBO
Geser ke kanan (dikurangi) 7 kali BERAPAKAH NILAI DARI TIGA PANGKAT DUA? TIGA, EMPAT, DELAPAN, SEMBILAN, SEPULUH
Geser ke kiri (ditambah) 7 kali PSFODOYOV BWZOW ROFW HWUO DOBUYOH RIO? HWUO, SADOH, RSZODOB, GSAPWZOB, GSDIZIV

Untuk membuka sandi, ternyata yang diperlukan adalah geser ke kanan (dikurangi). Jadi, jawabannya adalah ZLTIPSHU (SEMBILAN).

Sudah, ya. Sampai jumpa!

Bonus: Program Python

alfabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
teks = "ILYHWHRHO UPSHP KHYP APNH WHUNRHA KBH? APNH, LTWHA, KLSHWHU, ZLTIPSHU, ZLWBSBO"
k = 7
hasil = ""
for h in teks:
	j = alfabet.find(h)
	if j == -1: # bukan karakter yang bisa digeser
		hasil += h
	else:
		hasil += alfabet[(j - k) % len(alfabet)] # geser ke kanan
print(hasil) # BERAPAKAH NILAI DARI TIGA PANGKAT DUA? TIGA, EMPAT, DELAPAN, SEMBILAN, SEPULUH

Minggu, 31 Maret 2024

Ramadan Pertama di Perantauan

Halo!

Ini malam ke-22 Ramadan tahun ini (aku ikut mulai puasa tanggal 11 Maret 2024). Ramadan ini adalah Ramadan pertamaku di perantauan. Ini pertama kali aku memasuki bulan Ramadan jauh dari rumah.

Hal pertama yang kulakukan jelang bulan Ramadan adalah mencari masjid yang memulai Tarawih pada tanggal 10 Maret (malam 11 Maret). Di daerah sekitar UI, mayoritas masjid baru memulai Tarawih pada tanggal 11 Maret (malam 12 Maret) dan melakukan Tarawih sebanyak 23 rakaat (20 Tarawih + 3 Witir).

Pada tanggal 10 Maret sore, aku mencoba salat Magrib di Masjid Nurul Jannah yang kata warga sekitar melakukan Tarawih sebanyak 11 rakaat (8 Tarawih + 3 Witir). Tempatnya lebih jauh daripada tempat aku biasa salat wajib. Namun, karena keluargaku ikut mulai puasa tanggal 11 Maret 2024, aku pun mencoba ke sana dengan harapan masjid tersebut memulai Tarawih pada tanggal 10 Maret.

Aku pun ikut salat Magrib di Masjid Nurul Jannah. Setelah itu, aku pun memeriksa papan pengumuman masjid itu. Rupanya, telah tertempel jadwal imam Tarawih untuk Ramadan tahun ini. Alhamdulillah, jadwalnya dimulai pada tanggal 10 Maret! Malamnya, aku pun salat Tarawih di sana.

Setelah Tarawih, aku pergi ke warteg dekat masjid tempat aku biasa makan malam. Aku makan malam di sana, sekaligus membeli bekal untuk sahur besok paginya. Aku pun kembali ke kos. Beli makan di warteg untuk makan malam dan bekal sahur seperti ini kulakukan terus sampai hari ini, kecuali ketika wartegnya tutup.

Besok sorenya, aku pergi ke Masjid Nurul Jannah lagi untuk mencoba ikut buka bersama di masjid. Karena aku datang mepet, barisannya sudah penuh dan aku menyempil di ujung. Saat aku datang, ada dua pemuda yang juga baru datang dan mereka duduk bersebelahan denganku. Aku mencoba berkenalan dengan mereka. Rupanya, mereka sama-sama satu kos dan juga sama-sama mahasiswa Vokasi UI; salah satunya mengambil prodi Terapi Okupasi.

Hal baru yang kuketahui adalah bahwa program studi Terapi Okupasi baru ada dua di Indonesia, yaitu di UI dan di Poltekkes Surakarta.

Namun, aku tidak hanya Tarawih di Masjid Nurul Jannah. Aku juga mencoba Tarawih di tempat yang lebih dekat, yaitu Musholla Al-Ikhlas tempat aku biasa salat wajib. Di musala itu, Tarawih yang dilakukan sebanyak 23 rakaat, tetapi tidak ada kultum. Aku salat Tarawih bergantian di antara dua tempat itu.

Pada suatu malam, saat aku Tarawih di Masjid Nurul Jannah, ada kultum yang malah "kuliah tujuh (belas) menit". Aku pun jadi enggan lagi Tarawih di sana dan memutuskan untuk Tarawih di Musholla Al-Ikhlas untuk seterusnya, terlebih di Musholla Al-Ikhlas, ada pendingin ruangan (AC). He-he.

Tarawih 23 Rakaat

Aku baru pernah salat Tarawih 23 rakaat sekali sebelum ke Depok, yaitu saat mencoba Tarawih di Masjid Raya Sheikh Zayed di Surakarta. Itu pun hanya sekali. Jadi, ini pengalaman pertama bagiku untuk Tarawih 23 rakaat yang lebih dari semalam berturut-turut.

Hal yang baru bagiku adalah konsep seruan bilal (muazin) dalam rangkaian salat Tarawih. Hal ini belum pernah kualami sebelumnya, termasuk saat Tarawih di Masjid Sheikh Zayed.

Rangkaian Tarawih yang dilakukan sebanyak 23 rakaat dengan salam tiap 2 rakaat. Di antara salam, ada seruan bilal yang berisi permohonan kepada Allah Swt., selawat kepada Rasulullah saw., dan mengenang Khulafaur-Rasyidin. Setelah tiap seruan tersebut, ada balasan dari jemaah Tarawih.

Selain itu, ada juga baca doa bersama setelah Tarawih selesai (setelah rakaat ke-20) sebelum Witir dimulai serta ada baca doa dan niat puasa untuk besoknya setelah Witir selesai (setelah rakaat ke-23). Jadi, ada jeda lumayan untuk istirahat setelah salam sebelum salat berikutnya.

Tarawih memiliki akar kata yang sama dengan istirahat, yaitu ر و ح (ra-wa-ḥa).

Pada sepuluh malam terakhir, ada doa kunut (qunut) pada rakaat terakhir Witir (rakaat ke-23) setelah iktidal sebelum sujud pertama. Nah, ini yang hampir buatku terlupa dan hampir sujud.

Penutup

Aku tinggal beberapa hari lagi puasa Ramadan di Depok. Aku pulang kampung beberapa hari lagi insyaallah. Jadi, aku masih bisa mengikuti Tarawih versi masjid dekat rumahku.

Sepertinya itu saja yang terpikir untuk kutulis saat ini. Sampai jumpa!

Sabtu, 24 Februari 2024

Teorema De Morgan: Penyederhanaan Pernyataan Logika

Halo!

Pernahkah kalian menemui sebuah pernyataan logika yang tampak rumit dan sulit dipahami?

Misalnya, kita ingin mencari inversi pernyataan logika sederhana ini:

usia ≥ 18 atau punya izin khusus

Inversinya berikut ini:

tidak (usia ≥ 18 atau punya izin khusus)

Hmm, tidak memenuhi A atau B? Cukup rumit, ya. Bagaimana menyederhanakannya?

Dalam aljabar logika, terdapat sifat/identitas teorema De Morgan. Aku pertama kali tahu tentang teorema ini saat mengambil mata kuliah Sistem Digital (semester 1).

Teorema De Morgan menyatakan berikut:

  • ¬(A ∧ B) = ¬A ∨ ¬B
  • ¬(A ∨ B) = ¬A ∧ ¬B

Jadi, kita bisa menyederhanakan penyataan tadi sebagai berikut:

tidak (usia ≥ 18 atau punya izin khusus)
→ usia < 18 dan tidak punya izin khusus

Nah, setelah menggunakan sifat tadi, pernyataannya lebih mudah dipahami.

Semoga membantu dan selamat menerapkannya!

Sabtu, 20 Januari 2024

Semester Pertama di UI, Depok

Halo!

Kalau disebut pos tahun baru, ini sudah terlambat 19 hari. Hanya saja, aku ingin menulis sesuatu bulan ini. Sepertinya, cerita tentang diri sendiri juga baik. Aku juga masih buntu dalam memikirkan topik tulisan tentang kode atau pemrograman.

Sudah satu semester berlalu dalam perjalanan studi magisterku di UI, Depok. Saat ini masih dalam masa liburan semester. Semester dua sebentar lagi akan dimulai. Banyak hal baru yang kualami selama berada di perantauan (kesannya jauh sekali, tetapi memang cukup jauh). Aku bertemu banyak teman baru, suasana baru, budaya baru, bahasa baru, dan teknologi baru selama berada di kawasan yang sekarang punya singkatan Jabodetabekpunjur.

Walau mungkin juga sudah mengalaminya waktu kuliah sarjana, pertemanan kali ini berbeda karena akulah yang merantau (dari jauh). Sebelumnya, aku jadi "tuan rumah" (dekat sekali jarak rumah ke kampus), sedangkan teman-temankulah yang dari jauh. Aku juga bertemu orang-orang dari berbagai usia: ada yang baru saja mendapat gelar sarjana, ada yang sudah bekerja, ada yang sudah punya anak, dan ada yang sudah berambut putih. Tiap-tiap dari mereka punya kisah hidup yang unik.

Tempat di sekitar perguruan tinggi "populer" merupakan pencampuran budaya dari berbagai daerah di Indonesia. Aku menemukan banyak pedagang dan pengusaha yang merantau ke sana untuk berdagang atau membuka usaha, seperti rumah makan dan toko kelontong. Beberapa di antaranya sudah berhasil dan sudah berdagang atau menjalankan usahanya selama bertahun-tahun.

Untuk hal makanan, aku belum terpikir untuk mencoba banyak jajanan yang dijual di sana (lebih karena memang malas pergi, memang mager parah), padahal wilayah di sekitar instansi pendidikan terkenal dengan banyak penjual makanan/jajanan. Sebagian makan besarku di warteg: pilihan makanannya aman buatku. Meski begitu, aku juga mencoba banyak rumah makan yang ada di sekitar kampus.

Mengembalikan alat makan ke tempat khusus di kantin memang sederhana, tetapi tidak semua kampus menerapkan budaya ini. Itu salah satu budaya baru yang kualami di UI. Untuk kasus spesifik tersebut, baru kantin FK yang menerapkannya di UNS setahuku. Di sisi akademik, setidaknya yang kutahu, mahasiswa bisa ikut masuk kursus mata kuliah di EMAS (atau Scele untuk Fasilkom) tanpa mengambil mata kuliah tersebut secara resmi. Jadi, mahasiswa bisa ikut belajar tanpa berdampak pada nilai. Namun, aku belum tahu apakah hal itu kebijakan kampus, fakultas, atau dosen.

"Lu-gue end!" mungkin jadi kalimat yang cukup terkenal di sinetron. Namun, kata ganti lu dan gue memang lazim digunakan remaja di sana. Aku yang bukan asli orang sana lebih memilih saya-Pak/Bu-Mas/Mbak/Kak. Kata-kata lu/gue kayaknya bakal wagu kalau kuucapkan. Selain itu, ada teman kos yang orang Sunda. Jadi, aku cukup terpapar dengan suara bahasa Sunda.

Momen terbesar bagiku adalah bahwa ini pertama kali aku tinggal mandiri jauh dari rumah (tidak bisa tiap saat pulang ke rumah) dan pertama kali pula mengekos. Alhamdulillah, kos yang kusewa nyaman untuk ditinggali. Seperti kisah orang-orang yang merantau pertama kali, aku juga kadang terpikir bahwa sulit untuk tiba-tiba pulang kalau terjadi apa-apa. Jadi, aku perlu survei hal-hal di sekitar untuk persiapan kalau-kalau ada masalah yang terjadi.

Sepertinya itu saja yang terpikir untuk kutulis saat ini. Ide untuk mengepos ini tiba-tiba muncul dan, karena sempat, langsung kutuliskan saja di sini daripada terlupakan. Sampai jumpa!