Simulasi lempar dadu, pengacakan urutan kartu, sampai pembuatan token keamanan: ketiganya tampak seperti “angka acak”, padahal kebutuhannya berbeda. Python menyediakan dua module yang sering dipertukarkan secara keliru: random untuk acakan yang dapat direproduksi, dan secrets untuk nilai yang tidak boleh bisa ditebak penyerang. Pada Chapter ini kita membedah keduanya beserta batas keamanannya.
Module random dan Peran seed #
Module random menghasilkan angka pseudo-random menggunakan algoritma Mersenne Twister. Karena berbasis algoritma, hasilnya bisa direproduksi selama kita menetapkan titik awal yang sama dengan random.seed():
import random
random.seed(42)
print(random.randint(1, 6))
print(random.randrange(0, 100, 5))
print(random.random())
print(random.uniform(20.0, 30.0))
print(random.choice(["Budi", "Siti", "Andi"]))Output yang Dihasilkan:
6
15
0.025010755222666936
22.75029318369119
BudiMari kita bedah kode di atas:
- Baris 3 (
random.seed(42)): menetapkan titik awal generator. Dengan seed yang sama, seluruh rangkaian hasil acak berikutnya selalu identik di mesin mana pun. Inilah sebabnya contoh di Chapter ini punya output yang bisa Anda reproduksi. - Baris 5 (
random.randint(1, 6)): mengembalikan integer acak dalam rentang inklusif1sampai6— cocok untuk simulasi dadu. - Baris 6 (
random.randrange(0, 100, 5)): sepertirange(), batas atas tidak ikut diambil; function ini memilih dari kelipatan5antara0dan95. - Baris 7 (
random.random()): mengembalikan float antara0.0dan1.0(batas atas tidak termasuk). - Baris 8 (
random.uniform(20.0, 30.0)): mengembalikan float acak dalam rentang tertentu. - Baris 9 (
random.choice(...)): memilih satu elemen acak dari sebuah sequence.
Mengacak Urutan dan Mengambil Sampel #
Dua operasi lain yang sangat sering dibutuhkan adalah mengacak urutan list dan mengambil sampel tanpa pengulangan:
import random
random.seed(7)
kartu = ["as-keriting", "dua-hati", "tiga-wajik", "empat-pikir", "lima-keriting"]
random.shuffle(kartu)
print(kartu)
nomor_lotre = random.sample(range(1, 55), 6)
print(nomor_lotre)Output yang Dihasilkan:
['lima-keriting', 'as-keriting', 'empat-pikir', 'dua-hati', 'tiga-wajik']
[5, 53, 35, 7, 24, 38]Function shuffle() mengacak list di tempat (in place) dan mengembalikan None, jadi kita membaca variabel kartu setelahnya, bukan menampung nilai baliknya. Sementara sample(populasi, k) mengambil k elemen berbeda tanpa mengubah populasi aslinya — pola yang tepat untuk undian atau pengambilan sampel data.
Module secrets untuk Kebutuhan Keamanan #
Module random didesain cepat dan bisa direproduksi, sehingga nilainya bisa diprediksi siapa pun yang mengetahui algoritma dan seednya. Untuk token sesi, password, atau URL reset, gunakan module secrets yang mengambil entropi dari sistem operasi:
import secrets
print(secrets.token_hex(16))
print(secrets.randbelow(1000))
import string
alfabet = string.ascii_letters + string.digits
password = "".join(secrets.choice(alfabet) for _ in range(16))
print(password)Output yang Dihasilkan (nilai token berbeda di setiap eksekusi):
58be6ff5078bb5107a1dd6f73ce6bb5a
123
YntOsVympkFfbrMnMari kita bedah kode di atas:
- Baris 3 (
secrets.token_hex(16)): menghasilkan string heksadesimal dari 16 byte acak — 32 karakter — pola standar untuk token CSRF atau API key. - Baris 4 (
secrets.randbelow(1000)): mengembalikan integer acak0sampai999, miriprandrange()tetapi bersumber dari generator yang aman secara kriptografis. - Baris 8 (
secrets.choice(alfabet)): memilih satu karakter darialfabet; generator expression mengulanginya 16 kali lalu"".join(...)merangkai hasilnya menjadi satu password.
Batas Keamanan random vs secrets #
Perbedaan keduanya bukan soal kualitas angka, melainkan sumber dan konsekuensinya:
| Aspek | random | secrets |
|---|---|---|
| Sumber | Algoritma Mersenne Twister + seed | Entropi sistem operasi |
| Dapat diprediksi | Ya, bila seed diketahui | Tidak praktis diprediksi |
| Bisa di-reproduksi | Ya, dengan seed() | Tidak (memang begitu tujuannya) |
| Cocok untuk | Simulasi, game, sampling data | Token, password, API key |
| Kecepatan | Cepat | Lebih lambat (wajar) |
Dengan pembagian tugas yang jelas ini — random untuk simulasi yang jujur, secrets untuk rahasia yang harus tetap rahasia — kita bisa memilih module yang tepat sejak awal tanpa menulis ulang kode saat aplikasi tumbuh.