- Karya pemenang xmas.c dari International Obfuscated C Code Contest 1988 adalah kode C yang tampak seperti hasil ketikan acak, tetapi mencetak lirik The Twelve Days of Christmas
- Di dalam kode yang lebih kecil daripada keluarannya, terdapat string terenkripsi, lalu kata dan frasa didekripsi dengan substitution cipher dan pemanggilan rekursif
- Jika operator ternary diuraikan menjadi blok
if-then-elsedan diberi namawordssertashift, akan terlihat struktur di mana nilaitmengubah alur rekursi shiftmemasangkan karakter di bagian depan dengan karakter 31 posisi setelahnya, danwordsberisi potongan lirik terenkripsi yang dipisahkan oleh garis miring (/)- Meski hanya program sederhana untuk mencetak lirik, kombinasi substitution cipher, rekursi dua arah, kode yang tidak perlu, dan argumen yang tidak digunakan menjadikannya contoh obfuscation C yang kreatif
Apa yang dicetak oleh xmas.c
- xmas.c adalah program C pemenang International Obfuscated C Code Contest 1988
- Sang analis pertama kali melihat program ini sekitar tahun 2000, lalu membongkar kodenya pada November 2008 untuk memahami cara kerjanya
- Jika dikompilasi dan dijalankan tanpa argumen, program ini mencetak lirik lagu Natal The Twelve Days of Christmas dari hari pertama hingga hari kedua belas
- Komentar pada kode asli menyebut bahwa program ini bahkan lebih kecil daripada bentuk “terkompresi” dari keluarannya, dan para juri merasa tampilannya seperti “hasil menekan mesin tik tua secara acak”
Struktur internal yang diuraikan agar mudah dibaca
- Langkah pertama dalam analisis adalah mengubah semua bentuk
a ? b : cmenjadi blok if-then-else yang eksplisit - Dua string yang sulit dipahami diberi nama sesuai perannya
words: kumpulan kata dan frasa terenkripsi untuk membentuk lirik lagu Natalshift: string substitusi untuk mengubah karakter terenkripsi menjadi karakter keluaran yang sebenarnya
main()dimulai denganxmas(1, 0, '\0'), dan setelah itu satu fungsixmas()menangani seluruh keluaran secara rekursif- Variabel
tadalah nilai kunci yang mengendalikan arah rekursi dan perilaku percabangan
Substitution cipher dan data lirik
- String shift pada praktiknya bekerja seperti dua string yang disambungkan
- Karakter yang ditemukan di separuh depan didekripsi menjadi karakter yang berada 31 posisi setelahnya
- Misalnya, karakter pertama
!pada string itu berpasangan dengan karakter baris baru yang berada 31 posisi kemudian
- Misalnya, karakter pertama
- Cabang
t < -50menggeser stringasatu karakter demi satu sampai karakter input_ditemukan di dalamshift- Saat karakter yang cocok ditemukan, fungsi mencetak
a[31]lalu mengembalikan nilai
- Saat karakter yang cocok ditemukan, fungsi mencetak
- String
wordsadalah data lirik terenkripsi yang diuraikan dengan substitution cipher- Bentuk ordinal dan potongan lirik tiap bait dipisahkan oleh karakter garis miring (
/)
- Bentuk ordinal dan potongan lirik tiap bait dipisahkan oleh karakter garis miring (
Peran setiap cabang rekursif
- Cabang
t < -72memanggil ulang fungsi dengan dua argumen pertama ditukar danwordsdiberikan sebagai argumen ketiga- Tujuan utamanya adalah membingungkan pembaca, sekaligus memungkinkan rekursi bersarang yang mengabaikan argumen ketiga
- Cabang
t < 0mencari garis miring (/) ke-|t| di dalam string, lalu meneruskan string mulai dari karakter setelahnya - Cabang
t == 0mendekripsi dan mencetak string sampai garis miring berikutnya muncul, lalu mengembalikan1 - Cabang
t == 1dipanggil hanya sekali saat awal untuk memulai rekursi utama denganxmas(2, 2, "%s") - Cabang
t == 2mencetak baris pertama dalam format"On the [ordinal] day of Christmas my true love gave to me\n" - Dua blok kondisi terakhir mempertahankan rekursi dalam dua arah
- Menuruni tanggal saat ini dan mencetak lirik bait tersebut dalam urutan terbalik
- Menaikkan tanggal hingga hari ke-12 sambil mengulang seluruh bait
Alur eksekusi yang terlihat setelah disederhanakan
- Setelah perilakunya dipahami, kode ini dapat diubah menjadi versi yang jauh lebih sederhana dengan loop dan rutin pustaka string C
- Bahkan pada versi yang disederhanakan, data inti
wordsdanshifttetap dipertahankan - Cabang
t < 0menggunakanindex(a, '/')untuk menemukan pemisah garis miring dan berpindah ke posisi potongan lirik yang diinginkan - Cabang
t == 0mendekripsi karakter dan mencetaknya denganindex(shift, *a++)[31] - Cabang
t == 2mencetak bagian awal satu bait dalam urutan berikut"On the "- ordinal untuk hari tersebut
" my true love gave to me\n"
Mengapa obfuscation ini menarik
- Jika terus disederhanakan sampai akhir, program ini pada dasarnya menjadi kode yang mencetak lirik
- Namun versi aslinya menggunakan substitution cipher dan rekursi bersama-sama untuk membentuk struktur yang jauh lebih rumit daripada sekadar pencetak keluaran sederhana
- Potongan kode kecil yang tidak perlu dan argumen acak yang sebenarnya tidak digunakan membuat kode ini semakin sulit dipahami
- Memahami kode seperti ini berbeda dengan menulisnya sendiri, dan xmas.c dinilai sebagai contoh kreatif dari kode C
1 komentar
Komentar Hacker News
Di dunia TeX juga ada contoh serupa, yaitu
xii.texJika isi ini dimasukkan ke file
.tex, menjalankanpdftex, lalu melihat PDF hasilnya, tampilannya seperti ini: https://shreevatsa.net/post/xii/Saya menyimpannya saat pertama kali dipublikasikan, tetapi berbeda dari nama file di artikel ini, file saya bernama
carol.cSaat saya kompilasi dan jalankan di sistem modern, pada
gcc -o carol carol.cmuncul peringatan sepertireturn type defaults to ‘int’,type of ‘t’ defaults to ‘int’, dantype of ‘_’ defaults to ‘int’intimplisit tidak akan lagi diizinkan: https://fedoraproject.org/wiki/Changes/PortingToModernC#Remo...xmas()di dalammainsebelum didefinisikanJika dikompilasi dengan GCC di macOS, muncul error
ISO C99 and later do not support implicit function declarations; kalaumain()dipindahkan ke bawah, program terkompilasi dengan benar dan menghasilkan output yang tepatMelihat ini membuat saya teringat pada kompleksitas Kolmogorov
Program ini tampak seperti omong kosong, tetapi karena menghasilkan output yang diinginkan, saya jadi penasaran apakah ada program yang menghasilkan output yang sama tetapi lebih pendek dan tampak lebih tidak masuk akal
Bagaimana cara menemukan program seperti itu?
Namun pencarian brute force sangat tidak efisien, jadi jawaban realistisnya kira-kira adalah “lakukan dengan cerdas” dalam arti matematis
Secara umum, kompleksitas Kolmogorov tidak dapat dihitung, sehingga tidak ada program yang, ketika diberi sebuah string, dapat mengembalikan program terpendek yang menghitung string tersebut
Meski begitu, pada prinsipnya mungkin saja seseorang membuktikan bahwa kompleksitas Kolmogorov untuk string tertentu adalah X
Karena itu, ini cocok untuk kompetisi dan kontes jangka panjang, dan karena kurva pertumbuhannya seperti log, penemuan menarik kadang muncul di bagian paling ujung
Saat ini saya sedang mengadakan mini-kontes hingga Maret tahun depan untuk LLM yang mampu menghafal digit pi terbanyak; hadiah saat ini 100 dolar dan akan dibagikan sesuai proporsi kontribusi di ruang log
Karena pi secara teoretis cukup dapat dikompresi, menarik untuk melihat apakah model dapat mempelajari himpunan bobot yang mendekati minimum description length (MDL) untuk merekonstruksi algoritme berkompresi tinggi dari data
Namun belum jelas apakah ini bisa dilakukan dengan model siap pakai, jadi untuk sekarang saya akan membiarkannya sebagai kontes menghafal digit dan mengamatinya
Penjelasannya bagus, dan IOCCC tampaknya masih terus hidup pada 2023: https://www.ioccc.org/years.html
Namun di beranda ada pembaruan Mei 2023 yang mengatakan mereka “berencana mengadakan IOCCC ke-28”
Ada hal-hal yang layak ditunggu, seperti rilis Nethack
Baru-baru ini saya mengetahui hal menarik tentang The Twelve Days of Christmas: semua hadiahnya adalah jenis burung
Bahkan para wanita yang melompat dan para bangsawan pun katanya begitu
Menurut Wikipedia, publikasi lirik paling awal yang diketahui adalah buku anak bergambar Mirth Without Mischief yang terbit di London pada 1780: https://en.wikipedia.org/wiki/The_Twelve_Days_of_Christmas_(...
Situs ini berusaha menghubungkan semuanya dengan burung https://www.birdspot.co.uk/culture/the-birds-of-the-twelve-d..., tetapi terutama pada Five Gold Rings argumennya jadi sangat dipaksakan
Di Mirth and Mischief ada ilustrasi yang jelas menggambarkan cincin sebagai perhiasan, dan pemindaian salinannya juga ada di Archive.org: https://archive.org/details/mirth_without_mischief/page/n7/m...
Ada juga hasil riset yang saya lakukan sendiri lebih dari 20 tahun lalu: http://michaeldnahas.com/xmassong/index.html
Jika peringatannya dimatikan, ini masih berjalan bahkan di trunk: https://compiler-explorer.com/z/hGvs1e9jo
Ini mengingatkan saya pada kenangan indah pada 2022, saat dua semester terakhir saya di universitas, ketika dosen menunjukkan potongan kode ini begitu kuliah dimulai
Saya tidak bisa membedakan apakah itu serius atau komedi yang sangat datar
Saya ingat saat kuliah, dosen saya memasukkan ini ke materi cetak bahasa C, jadi suatu kali saya pernah mengetiknya sendiri dengan tangan
Di Rosetta Code juga ada tugas serupa
Yaitu program untuk mencetak Old Lady Swallowed a Fly, lagu yang bertambah secara berulang: https://rosettacode.org/wiki/Old_lady_swallowed_a_fly
puts [zlib inflate [binary decode base64 "7VRNa8MwDL3nV2(...)"]]https://rosettacode.org/wiki/Old_lady_swallowed_a_fly#Tcl
Python, Nim, Julia, dan lainnya kemungkinan besar juga punya versi serupa