Cara pengundian bekerja — contoh nyata

Ikuti satu pengundian berbentuk nyata dari awal hingga akhir: 1.000 komentar yang memenuhi syarat, 3 pemenang, 9 cadangan. Tanpa jargon, tanpa penjelasan kabur.

Skenario

Bayangkan kontes sudah berakhir. Komentar telah diambil, filter kontes telah berjalan, dan 1.000 entri memenuhi syarat. Hadiahnya memberikan 3 pemenang dengan 9 cadangan, jika ada pemenang yang tidak dapat dihubungi. Inilah probabilitas per entri — identik untuk setiap satu dari 1.000 komentar yang memenuhi syarat, terlepas dari kapan diposting atau seberapa panjang nama komentator.

Hasil Peluang untuk satu entri
Diundi sebagai pemenang utama (posisi 1–3) 3 dari 1.000 — 0,30%
Diundi sebagai cadangan (posisi 4–12) 9 dari 1.000 — 0,90%
Diundi ke slot kemenangan mana pun 12 dari 1.000 — 1,20%

Tidak ada yang berubah dari ini jika kontes memiliki 444 komentar atau 444.444. Algoritmanya identik. Hanya penyebutnya yang bergerak.

Langkah 1 — Kumpulkan dan filter entri

Aplikasi mengambil setiap komentar pada postingan Facebook atau Instagram yang Anda hubungkan, kemudian menerapkan filter kontes — duplikat, kata terlarang, aturan usia akun, apa pun yang dikonfigurasi. Yang lolos adalah kumpulan yang memenuhi syarat. Dalam skenario kami, itu adalah 1.000 komentar. Setiap komentar memiliki baris database dengan ID numerik unik; 1.000 ID itulah yang menjadi dasar pengundian selanjutnya.

Langkah 2 — Urutkan ke dalam urutan kanonik

Sebelum apa pun yang acak terjadi, aplikasi mengurutkan 1.000 ID dalam urutan numerik ascending yang ketat — 17, 142, 203, 1058, 9941, … — dan membuang urutan kedatangan mereka. Mengapa? Karena Facebook dapat mengembalikan komentar dalam urutan berbeda tergantung pada paginasi, waktu, atau perubahan back-end. Jika pengundian menggunakan urutan Facebook, dua pengambilan ulang bisa menghasilkan pemenang berbeda dari seed acak yang sama. Mengurutkan terlebih dahulu mengunci input ke satu daftar kanonik, sehingga seed saja yang menentukan hasilnya.

Langkah 3 — Kunci daftar input dengan hash SHA-256

Daftar yang diurutkan dimasukkan ke SHA-256 — fungsi hash kriptografi — menghasilkan sidik jari 64 karakter. Sidik jari tersebut, bersama daftar lengkapnya, disimpan pada catatan kontes. Mulai saat ini, siapa pun yang memeriksa kontes dapat memastikan daftar yang memenuhi syarat tidak diubah: hash ulang daftar yang dipublikasikan, bandingkan dengan sidik jari yang tersimpan, dan satu ID yang diubah akan menghasilkan hash yang sama sekali berbeda. Tidak ada cara untuk diam-diam menambah atau menghapus komentar setelah langkah ini tanpa terlihat.

Langkah 4 — Buat seed acak 256-bit

Aplikasi meminta sumber acak kriptografi sistem operasi (SecureRandom.hex(32)) untuk 32 byte keacakan yang tidak dapat diprediksi, dan menyimpan hasilnya sebagai string heksadesimal 64 karakter — misalnya a3f1…ce. 256 bit berarti 2²⁵⁶ ≈ 10⁷⁷ kemungkinan seed. Sebagai gambaran, alam semesta yang dapat diamati mengandung sekitar 10⁸⁰ atom. Tidak seorang pun — bukan pembuat kontes, bukan operator, bukan penyerang yang mengamati dari luar — dapat memprediksi atau menebak seed ini sebelum dihasilkan.

Langkah 5 — Acak 1.000 ID, lalu ambil 12 pertama

Seed menginisialisasi mesin pengacakan deterministik, yang kemudian melakukan shuffle Fisher–Yates pada 1.000 ID yang diurutkan. Fisher–Yates adalah algoritma shuffle adil standar — setiap satu dari 1.000 entri memiliki peluang yang sama untuk berakhir di setiap posisi. Setelah shuffle, aplikasi mengambil 12 entri pertama dari atas. Itulah seluruh langkah seleksi: acak, ambil 12.

Langkah 6 — Tetapkan posisi

12 entri yang dipilih ditelusuri secara berurutan. Tiga pertama menjadi pemenang 1, 2, dan 3, dan sembilan berikutnya menjadi cadangan 1 hingga 9. 988 entri yang memenuhi syarat lainnya dicatat sebagai tidak terpilih. Komentar yang difilter sebelumnya ditandai sebagai didiskualifikasi beserta alasan spesifik mengapa mereka tidak memenuhi syarat.

Langkah 7 — Publikasikan semuanya

Terakhir, aplikasi menyimpan lima bukti pada catatan kontes — semuanya dapat dibaca publik. Tanpanya, hasilnya akan menjadi kotak hitam. Dengannya, siapa pun dapat mereproduksi seluruh pengundian di rumah dan memastikan pemenang yang dipublikasikan adalah satu-satunya pemenang yang dapat dihasilkan seed tersebut.

Apa yang dipublikasikan dengan setiap pengundian

Masing-masing ini disimpan pada kontes dan diekspos melalui halaman verifikasi publik. Bersama-sama mereka membuat pengundian sepenuhnya dapat direproduksi — input yang sama, output yang sama, selalu.

  • Seed acak 256-bit — string hex 64 karakter dari Langkah 4.
  • Daftar ID yang memenuhi syarat yang diurutkan — semua 1.000 ID dari Langkah 2, dalam urutan kanonik.
  • Sidik jari SHA-256 dari ID — hash 64 karakter dari Langkah 3. Memastikan daftar yang dipublikasikan tidak diubah.
  • Versi algoritma — saat ini v1. Mengunci algoritma seleksi yang tepat, sehingga peningkatan di masa depan tidak pernah mengubah hasil lama secara retroaktif.
  • Versi Ruby — mengunci runtime bahasa, karena urutan shuffle yang tepat bergantung padanya.

Hitung ulang matematikanya sendiri — dalam lima baris

Jika Anda telah menginstal Ruby (sudah tersedia di macOS dan sebagian besar distribusi Linux), Anda dapat mereproduksi pengundian yang tepat di rumah. Setiap kontes mempublikasikan eligible-ids.txt-nya sendiri di halaman verifikasinya (pola URL: /results/<token>/verify) — panduan verifikasi memandu pengunduhan langkah demi langkah. Salin seed yang dipublikasikan dan tempelkan ini ke irb:

require "digest"
seed = "PASTE_THE_PUBLISHED_SEED_HERE"
ids  = File.read("eligible-ids.txt").split("\n").map(&:to_i).sort

# (1) Sanity check the input: must equal the published SHA-256.
Digest::SHA256.hexdigest(ids.join("\n"))

# (2) Re-run the shuffle. First 3 items are winners 1..3 (in order);
#     the next 9 items are reserves 1..9.
ids.shuffle(random: Random.new(seed.to_i(16))).first(12)

12 ID keluar dalam urutan yang persis sama dengan yang dipublikasikan kontes. Tiga pemenang, sembilan cadangan, identik bit per bit. Itulah yang membuat pengundian Pick a Winner dapat diverifikasi alih-alih sekadar dijanjikan — matematika yang melakukan pekerjaan, bukan kata-kata operator.

Mengapa ini sulit untuk dicurangi

  • Seed tidak dapat ditebak. 2²⁵⁶ kemungkinan, dibuat hanya setelah daftar yang memenuhi syarat dikunci. Tidak seorang pun dapat pra-menghitung ID mana yang akan disukai seed tersebut, karena seed tidak ada sampai saat pengundian.
  • Input dikunci. Sidik jari SHA-256 berarti Anda tidak dapat diam-diam menambahkan komentar dari teman setelah melihat seed — sidik jari akan berubah dan pengundian tidak lagi dapat direproduksi.
  • Shuffle bersifat mekanis. Begitu seed dan daftar yang diurutkan ada, pemenang sudah ditentukan. Tidak ada keputusan manusia di antara keduanya. Perubahan apa pun setelah fakta akan terlihat sebagai ketidakcocokan begitu siapa pun menghitung ulang matematikanya.
  • Tanda terimanya publik. Seed, daftar, hash, versi algoritma, versi Ruby — kelima-limanya dipublikasikan. Tidak ada bagian pribadi dari pengundian yang dapat diubah operator tanpa semua orang dapat melihatnya.