Bagaimana cara kerja sampel acak python?

Seberapa acak itu acak? . Setiap kali Anda membuat data, string, atau angka acak dengan Python, ada baiknya setidaknya memiliki gambaran kasar tentang bagaimana data itu dihasilkan

Di sini, Anda akan membahas beberapa opsi berbeda untuk menghasilkan data acak dengan Python, dan kemudian membuat perbandingan masing-masing dalam hal tingkat keamanan, keserbagunaan, tujuan, dan kecepatannya.

Saya berjanji bahwa tutorial ini tidak akan menjadi pelajaran dalam matematika atau kriptografi, yang saya tidak akan siap untuk mengajar di tempat pertama. Anda akan mempelajari matematika sebanyak yang diperlukan, dan tidak lebih

Seberapa Acak Itu Acak?

Pertama, penafian yang menonjol diperlukan. Sebagian besar data acak yang dihasilkan dengan Python tidak sepenuhnya acak dalam pengertian ilmiah dari kata tersebut. Sebaliknya, itu adalah pseudorandom. dihasilkan dengan pseudorandom number generator (PRNG), yang pada dasarnya adalah algoritma apa pun untuk menghasilkan data yang tampaknya acak tetapi masih dapat direproduksi

Angka acak “benar” dapat dihasilkan oleh, Anda dapat menebaknya, generator angka acak sejati (TRNG). Salah satu contohnya adalah berulang kali mengambil dadu dari lantai, melemparkannya ke udara, dan membiarkannya mendarat dengan cara yang mungkin.

Dengan asumsi bahwa lemparan Anda tidak memihak, Anda benar-benar tidak tahu di angka berapa dadu akan mendarat. Memutar dadu adalah bentuk kasar penggunaan perangkat keras untuk menghasilkan angka yang tidak deterministik sama sekali. (Atau, Anda dapat meminta dadu-o-matic melakukan ini untuk Anda. ) TRNG berada di luar cakupan artikel ini tetapi tetap layak disebutkan demi perbandingan

PRNG, biasanya dilakukan dengan perangkat lunak daripada perangkat keras, bekerja sedikit berbeda. Berikut deskripsi singkatnya

Mereka mulai dengan nomor acak, yang dikenal sebagai benih, dan kemudian menggunakan algoritme untuk menghasilkan urutan bit acak semu berdasarkan itu. (Sumber)

Anda kemungkinan besar telah diberitahu untuk “membaca dokumen. " dalam beberapa kasus. Yah, orang-orang itu tidak salah. Inilah cuplikan penting dari dokumentasi modul

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 yang tidak ingin Anda lewatkan

Peringatan. Generator acak semu dari modul ini tidak boleh digunakan untuk tujuan keamanan. (Sumber)

Anda mungkin pernah melihat

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
3,
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
4, atau sejenisnya, dengan Python. Pemanggilan fungsi ini menyemai generator bilangan acak dasar yang digunakan oleh modul
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 Python. Inilah yang membuat panggilan selanjutnya untuk menghasilkan angka acak yang deterministik. input A selalu menghasilkan output B. Berkat ini juga bisa menjadi kutukan jika digunakan dengan jahat

Mungkin istilah "acak" dan "deterministik" sepertinya tidak bisa berdampingan satu sama lain. Untuk membuatnya lebih jelas, inilah versi

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
6 yang sangat dipangkas yang secara iteratif membuat nomor "acak" dengan menggunakan
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
7.
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8 awalnya didefinisikan sebagai nilai benih dan kemudian berubah menjadi urutan angka deterministik berdasarkan benih itu

class NotSoRandom(object):
    def seed(self, a=3):
        """Seed the world's most mysterious random number generator."""
        self.seedval = a
    def random(self):
        """Look, random numbers!"""
        self.seedval = (self.seedval * 3) % 19
        return self.seedval

_inst = NotSoRandom()
seed = _inst.seed
random = _inst.random

Jangan menganggap contoh ini terlalu harfiah, karena ini dimaksudkan terutama untuk mengilustrasikan konsepnya. Jika Anda menggunakan nilai seed 1234, urutan panggilan berikutnya ke

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
6 harus selalu identik

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_

Anda akan segera melihat ilustrasi yang lebih serius tentang ini

Hilangkan iklan

Apa Itu “Aman Secara Kriptografis?”

Jika Anda belum muak dengan akronim "RNG", mari kita masukkan satu lagi ke dalam campuran. CSPRNG, atau PRNG yang aman secara kriptografis. CSPRNG cocok untuk menghasilkan data sensitif seperti kata sandi, autentikator, dan token. Diberi string acak, secara realistis tidak ada cara bagi Malicious Joe untuk menentukan string apa yang muncul sebelum atau sesudah string itu dalam urutan string acak

Satu istilah lain yang mungkin Anda lihat adalah entropi. Singkatnya, ini mengacu pada jumlah keacakan yang diperkenalkan atau diinginkan. Misalnya, satu Python yang akan Anda bahas di sini mendefinisikan

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
0, jumlah byte yang dikembalikan secara default. Pengembang menganggap ini sebagai byte yang "cukup" untuk menjadi jumlah kebisingan yang cukup

Catatan. Melalui tutorial ini, saya berasumsi bahwa satu byte mengacu pada 8 bit, seperti yang terjadi sejak tahun 1960-an, daripada unit penyimpanan data lainnya. Anda bebas menyebutnya oktet jika Anda mau

Poin kunci tentang CSPRNG adalah bahwa mereka masih pseudorandom. Mereka direkayasa dengan cara yang deterministik secara internal, tetapi mereka menambahkan beberapa variabel lain atau memiliki beberapa properti yang membuat mereka "cukup acak" untuk melarang dukungan ke fungsi apa pun yang memaksakan determinisme

Apa yang Akan Anda Bahas Di Sini

Secara praktis, ini berarti Anda harus menggunakan PRNG biasa untuk pemodelan statistik, simulasi, dan membuat data acak dapat direproduksi. Mereka juga jauh lebih cepat daripada CSPRNG, seperti yang akan Anda lihat nanti. Gunakan CSPRNG untuk aplikasi keamanan dan kriptografi di mana sensitivitas data sangat penting

Selain memperluas kasus penggunaan di atas, dalam tutorial ini, Anda akan mempelajari alat Python untuk menggunakan PRNG dan CSPRNG

  • Opsi PRNG termasuk modul
    >>> random.seed(444)
    >>> random.random()
    0.3088946587429545
    >>> random.random()
    0.01323751590501987
    
    >>> random.seed(444)  # Re-seed
    >>> random.random()
    0.3088946587429545
    >>> random.random()
    0.01323751590501987
    
    2 dari pustaka standar Python dan mitra NumPy berbasis arraynya,
    >>> random.randint(0, 10)
    7
    >>> random.randint(500, 50000)
    18601
    
    2
  • Modul
    >>> random.randint(0, 10)
    7
    >>> random.randint(500, 50000)
    18601
    
    3,
    >>> random.randint(0, 10)
    7
    >>> random.randint(500, 50000)
    18601
    
    4, dan
    >>> random.randint(0, 10)
    7
    >>> random.randint(500, 50000)
    18601
    
    5 Python berisi fungsi untuk menghasilkan objek yang aman secara kriptografis

Anda akan menyentuh semua hal di atas dan menyelesaikannya dengan perbandingan tingkat tinggi

PRNG dengan Python

Modul >>> random.seed(444) >>> random.random() 0.3088946587429545 >>> random.random() 0.01323751590501987 >>> random.seed(444) # Re-seed >>> random.random() 0.3088946587429545 >>> random.random() 0.01323751590501987 2

Mungkin alat yang paling banyak dikenal untuk menghasilkan data acak dengan Python adalah modul

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2, yang menggunakan algoritma Mersenne Twister PRNG sebagai generator intinya

Sebelumnya, Anda menyentuh sebentar

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_8, dan sekarang adalah saat yang tepat untuk melihat cara kerjanya. Pertama, mari buat beberapa data acak tanpa penyemaian. Fungsi
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_9 mengembalikan float acak dalam interval [0. 0, 1. 0). Hasilnya akan selalu kurang dari endpoint kanan (1. 0). Ini juga dikenal sebagai rentang semi-terbuka

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
_

Jika Anda menjalankan kode ini sendiri, saya berani bertaruh tabungan hidup saya bahwa angka yang dikembalikan pada mesin Anda akan berbeda. Saat Anda tidak menyemai generator adalah menggunakan waktu sistem Anda saat ini atau "sumber acak" dari OS Anda jika tersedia

Dengan

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_8, Anda dapat membuat hasil yang dapat direproduksi, dan rangkaian panggilan setelah
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
8 akan menghasilkan jejak data yang sama

>>> ________0______

Perhatikan pengulangan angka "acak". Urutan bilangan acak menjadi deterministik, atau sepenuhnya ditentukan oleh nilai seed, 444

Mari kita lihat beberapa fungsi yang lebih mendasar dari

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2. Di atas, Anda membuat pelampung acak. Anda dapat menghasilkan bilangan bulat acak antara dua titik akhir dengan Python dengan fungsi
>>> random.randrange(1, 10)
5
3. Ini mencakup interval [x, y] penuh dan dapat menyertakan kedua titik akhir

>>>

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_

Dengan

>>> random.randrange(1, 10)
5
_4, Anda dapat mengecualikan sisi kanan interval, artinya angka yang dihasilkan selalu terletak di dalam [x, y) dan akan selalu lebih kecil dari titik akhir kanan

>>>

>>> random.randrange(1, 10)
5
_

Jika Anda perlu membuat float acak yang berada dalam interval [x, y] tertentu, Anda dapat menggunakan

>>> random.randrange(1, 10)
5
5, yang diambil dari distribusi seragam kontinu

>>>

>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
_

Untuk memilih elemen acak dari urutan yang tidak kosong (seperti daftar atau tupel), Anda dapat menggunakan

>>> random.randrange(1, 10)
5
6. Ada juga
>>> random.randrange(1, 10)
5
_7 untuk memilih beberapa elemen dari urutan dengan penggantian (duplikat dimungkinkan)

>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']

Untuk meniru pengambilan sampel tanpa penggantian, gunakan

>>> random.randrange(1, 10)
5
8

>>>

>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
_

Anda dapat mengacak urutan di tempat menggunakan

>>> random.randrange(1, 10)
5
9. Ini akan memodifikasi objek urutan dan mengacak urutan elemen

>>>

>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
_

Jika Anda memilih untuk tidak memutasikan daftar asli, Anda harus membuat salinannya terlebih dahulu, lalu mengocok salinannya. Anda dapat membuat salinan daftar Python dengan modul

>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
0, atau hanya
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
1 atau
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
2, di mana
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8 adalah daftarnya

Sebelum melanjutkan untuk menghasilkan data acak dengan NumPy, mari kita lihat satu lagi aplikasi yang sedikit terlibat. menghasilkan urutan string acak unik dengan panjang seragam

Ini dapat membantu untuk memikirkan tentang desain fungsi terlebih dahulu. Anda harus memilih dari "kumpulan" karakter seperti huruf, angka, dan/atau tanda baca, menggabungkannya menjadi satu string, lalu memeriksa apakah string ini belum dibuat. Python

>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
_4 bekerja dengan baik untuk jenis pengujian keanggotaan ini

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_0

>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
5 menggabungkan huruf-huruf dari
>>> random.randrange(1, 10)
5
7 menjadi satu Python
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
7 dengan panjang
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
8. Token ini ditambahkan ke set, yang tidak dapat berisi duplikat, dan loop
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
9 dijalankan hingga set memiliki jumlah elemen yang Anda tentukan

Sumber. Modul

>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
0 Python berisi sejumlah konstanta yang berguna.
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
1,
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
2,
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
3,
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
4, dan beberapa lainnya

Mari kita coba fungsi ini

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
1

Untuk versi yang disempurnakan dari fungsi ini, jawaban Stack Overflow ini menggunakan fungsi generator, pengikatan nama, dan beberapa trik lanjutan lainnya untuk membuat versi

>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
5 yang lebih cepat dan aman secara kriptografis di atas

Hilangkan iklan

PRNG untuk Array. >>> random.randint(0, 10) 7 >>> random.randint(500, 50000) 18601 _2

Satu hal yang mungkin Anda perhatikan adalah bahwa sebagian besar fungsi dari

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 mengembalikan nilai skalar (satu
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
8,
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
9, atau objek lain). Jika Anda ingin menghasilkan urutan angka acak, salah satu cara untuk mencapainya adalah dengan pemahaman daftar Python

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
2

Tetapi ada opsi lain yang dirancang khusus untuk ini. Anda dapat menganggap paket

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
2 NumPy sendiri seperti
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 perpustakaan standar, tetapi untuk array NumPy. (Itu juga dilengkapi dengan kemampuan untuk menggambar dari lebih banyak distribusi statistik. )

Perhatikan bahwa

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_2 menggunakan PRNG sendiri yang terpisah dari
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 lama. Anda tidak akan menghasilkan array NumPy acak deterministik dengan panggilan ke
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
8 Python sendiri

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
3

Tanpa basa-basi lagi, berikut adalah beberapa contoh untuk membangkitkan selera Anda

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
4

Dalam sintaks untuk

>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
_5, parameter
>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
6 bersifat opsional dan menunjukkan bentuk objek akhir. Di sini,
>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
_7 membuat array 2d dengan 3 baris dan 4 kolom. Data akan menjadi i. i. d. , artinya setiap titik data diambil secara independen dari yang lain

Operasi umum lainnya adalah membuat urutan nilai Boolean acak,

>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
8 atau
>>> random.sample(items, 4)
['one', 'five', 'four', 'three']
9. Salah satu cara untuk melakukannya adalah dengan
>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
0. Namun, ini sebenarnya sekitar 4x lebih cepat untuk memilih dari
>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
1 dan kemudian menampilkan bilangan bulat ini ke nilai Boolean yang sesuai

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
5

Bagaimana dengan menghasilkan data yang berkorelasi? . Salah satu cara untuk melakukannya adalah dengan fungsi NumPy, yang memperhitungkan matriks kovarians. Dengan kata lain, untuk menggambar dari satu variabel acak yang terdistribusi normal, Anda perlu menentukan rata-rata dan variansnya (atau standar deviasi)

Untuk sampel dari distribusi normal multivariat, Anda menentukan rata-rata dan matriks kovarians, dan Anda berakhir dengan beberapa rangkaian data berkorelasi yang masing-masing kira-kira terdistribusi secara normal

Namun, daripada kovarians, korelasi adalah ukuran yang lebih familiar dan intuitif bagi sebagian besar orang. Ini adalah kovarians yang dinormalisasi oleh produk standar deviasi, sehingga Anda juga dapat menentukan kovarians dalam hal korelasi dan standar deviasi

Bagaimana cara kerja sampel acak python?

Jadi, bisakah Anda mengambil sampel acak dari distribusi normal multivariat dengan menentukan matriks korelasi dan standar deviasi? . Di sini, S adalah vektor standar deviasi, P adalah matriks korelasinya, dan C adalah matriks kovarians (kuadrat) yang dihasilkan

Bagaimana cara kerja sampel acak python?

Ini dapat dinyatakan dalam NumPy sebagai berikut

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_6

Sekarang, Anda dapat membuat dua deret waktu yang berkorelasi tetapi tetap acak

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
7

Anda dapat menganggap

>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
3 sebagai 500 pasang titik data yang berkorelasi terbalik. Inilah pemeriksaan kewarasan yang dapat Anda kembalikan ke input asli, yang kira-kira
>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
4,
>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
5, dan
>>> random.shuffle(items)
>>> items
['four', 'three', 'two', 'one', 'five']
6 dari atas

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
8

Sebelum kita beralih ke CSPRNG, mungkin berguna untuk meringkas beberapa fungsi

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 dan rekanan
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
2 mereka

Python

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 ModuleNumPy CounterpartUse
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
6Float acak di [0. 0, 1. 0)
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
02Random integer in [a, b]
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
04Random integer in [a, b)
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
06Random float in [a, b]
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
08Random element from
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
10
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
11Random
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
8 elements from
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
10 with replacement
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
15 with
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
17Random
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
8 elements from
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
10 without replacement
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
20Shuffle the sequence
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8 in place
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
23 or

Catatan. NumPy khusus untuk membangun dan memanipulasi array multidimensi yang besar. Jika Anda hanya membutuhkan satu nilai,

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 sudah cukup dan mungkin akan lebih cepat juga. Untuk urutan kecil,
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 bahkan mungkin lebih cepat juga, karena NumPy hadir dengan beberapa overhead

Sekarang setelah Anda membahas dua opsi mendasar untuk PRNG, mari beralih ke beberapa adaptasi yang lebih aman

Hilangkan iklan

CSPRNG dengan Python

>>> seed(1234) >>> [random() for _ in range(10)] [16, 10, 11, 14, 4, 12, 17, 13, 1, 3] >>> seed(1234) >>> [random() for _ in range(10)] [16, 10, 11, 14, 4, 12, 17, 13, 1, 3] _30. Tentang Acak yang Mendapat

Fungsi Python digunakan oleh keduanya dan (keduanya akan Anda lihat di sini sebentar lagi). Tanpa membahas terlalu banyak detail,

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_30 menghasilkan byte acak yang bergantung pada sistem operasi yang dapat dengan aman disebut aman secara kriptografis

  • Pada sistem operasi Unix, ia membaca byte acak dari file khusus

    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    35, yang pada gilirannya “memungkinkan akses ke kebisingan lingkungan yang dikumpulkan dari driver perangkat dan sumber lain. ” (Terima kasih, Wikipedia. ) Ini adalah informasi kacau yang khusus untuk perangkat keras dan status sistem Anda pada saat tertentu tetapi pada saat yang sama cukup acak

  • Di Windows, fungsi C++

    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    _36 digunakan. Fungsi ini secara teknis masih pseudorandom, tetapi bekerja dengan menghasilkan nilai benih dari variabel seperti ID proses, status memori, dan sebagainya.

Dengan

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_30, tidak ada konsep penyemaian secara manual. Meskipun secara teknis masih pseudorandom, fungsi ini lebih selaras dengan cara kita berpikir tentang keacakan. Satu-satunya argumen adalah jumlah yang akan dikembalikan

>>>

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
9

Sebelum kita melangkah lebih jauh, ini mungkin saat yang tepat untuk mempelajari pelajaran mini tentang pengkodean karakter. Banyak orang, termasuk saya, memiliki beberapa jenis reaksi alergi ketika mereka melihat

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
38 objek dan garis panjang
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
39 karakter. Namun, sangat berguna untuk mengetahui bagaimana urutan seperti
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8 di atas akhirnya diubah menjadi string atau angka

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_30 mengembalikan urutan byte tunggal

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
0

Tapi bagaimana ini akhirnya berubah menjadi Python

>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
7 atau urutan angka?

Pertama, ingat salah satu konsep dasar komputasi, yaitu satu byte terdiri dari 8 bit. Anda dapat menganggap bit sebagai satu digit yang bernilai 0 atau 1. Sebuah byte secara efektif memilih antara 0 dan 1 delapan kali, sehingga

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
43 dan
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
44 dapat mewakili byte. Coba ini, yang menggunakan f-string Python yang diperkenalkan di Python 3. 6, dalam juru bahasa Anda

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
1

Ini setara dengan

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_45, dengan beberapa pemformatan khusus. mengubah bilangan bulat menjadi representasi binernya sebagai string

Di mana itu meninggalkan kita? . (Tidak ada permainan kata-kata yang dimaksudkan. ) Mengingat bahwa kita diperbolehkan 8 bit, masing-masing dengan 2 pilihan, ada

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
48 kemungkinan byte “kombinasi. ”

Ini berarti bahwa setiap byte memetakan ke bilangan bulat antara 0 dan 255. Dengan kata lain, kita membutuhkan lebih dari 8 bit untuk menyatakan bilangan bulat 256. Anda dapat memverifikasi ini dengan memeriksa bahwa

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_49 sekarang adalah 9, bukan 8

Oke, sekarang mari kita kembali ke tipe data

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_38 yang Anda lihat di atas, dengan membuat urutan byte yang sesuai dengan bilangan bulat 0 hingga 255

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
2

Jika Anda memanggil

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_51, Anda akan kembali ke daftar Python yang berjalan dari 0 hingga 255. Tetapi jika Anda hanya mencetak
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_52, Anda mendapatkan urutan yang tampak jelek dengan garis miring terbalik

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
3

Garis miring terbalik ini adalah escape sequence, dan

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
53 karakter dengan nilai hex
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
54. Beberapa elemen
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
52 ditampilkan secara harfiah (karakter yang dapat dicetak seperti huruf, angka, dan tanda baca). Sebagian besar diekspresikan dengan pelarian.
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_56 mewakili backspace keyboard, sementara
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
57 adalah carriage return (bagian dari baris baru, pada sistem Windows)

Jika Anda memerlukan penyegaran pada heksadesimal, Kode Charles Petzold. Bahasa Tersembunyi adalah tempat yang tepat untuk itu. Hex adalah sistem penomoran berbasis 16 yang, alih-alih menggunakan 0 hingga 9, menggunakan 0 hingga 9 dan a hingga f sebagai digit dasarnya.

Terakhir, mari kembali ke awal, dengan urutan byte acak

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8. Semoga ini sedikit lebih masuk akal sekarang. Memanggil
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_59 pada objek
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
38 memberikan
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
7 angka heksadesimal, dengan masing-masing terkait dengan angka desimal dari 0 hingga 255

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
4

Satu pertanyaan terakhir. bagaimana

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_62 12 karakter di atas, padahal
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
8 hanya 6 byte? . Versi
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
_7 dari
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
38 akan selalu dua kali lebih panjang sejauh mata kita memperhatikan

Bahkan jika byte (seperti

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_66) tidak memerlukan 8 bit penuh untuk direpresentasikan,
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
62 akan selalu menggunakan dua digit hex per byte, sehingga angka 1 akan direpresentasikan sebagai
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
68 bukan hanya
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
69. Secara matematis, keduanya memiliki ukuran yang sama

Detil Teknis. Apa yang terutama Anda bedah di sini adalah bagaimana objek

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
38 menjadi Python
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
7. Salah satu teknis lainnya adalah bagaimana
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
38 diproduksi oleh
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
30 dikonversi menjadi
>>> items = ['one', 'two', 'three', 'four', 'five']
>>> random.choice(items)
'four'

>>> random.choices(items, k=2)
['three', 'three']
>>> random.choices(items, k=3)
['three', 'five', 'four']
9 dalam interval [0. 0, 1. 0), seperti pada
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_9. Jika Anda tertarik untuk mempelajarinya lebih lanjut, cuplikan kode ini menunjukkan bagaimana
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
76 membuat konversi awal menjadi bilangan bulat, menggunakan sistem penomoran basis-256

Dengan itu di bawah ikat pinggang Anda, mari kita sentuh modul yang baru diperkenalkan,

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4, yang membuat pembuatan token aman jauh lebih ramah pengguna

Hilangkan iklan

Penyimpanan Terbaik Python >>> random.randint(0, 10) 7 >>> random.randint(500, 50000) 18601 4

Diperkenalkan dengan Python 3. 6 oleh salah satu PEP yang lebih berwarna di luar sana, modul

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4 dimaksudkan untuk menjadi modul Python de facto untuk menghasilkan byte dan string acak yang aman secara kriptografis

Anda dapat melihat kode sumber untuk modul tersebut, yang pendek dan manis dengan sekitar 25 baris kode.

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_4 pada dasarnya adalah pembungkus sekitar
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
30. Itu hanya mengekspor beberapa fungsi untuk menghasilkan angka, byte, dan string acak. Sebagian besar contoh ini harus cukup jelas

>>>

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
5

Sekarang, bagaimana dengan contoh konkret? . com atau bit. ly yang mengubah URL yang berat menjadi sesuatu seperti https. //sedikit. ly/2IcCp9u. Kebanyakan shortener tidak melakukan hashing yang rumit dari input ke output;

Katakanlah setelah melihat Root Zone Database, Anda telah mendaftarkan situs tersebut. ly. Inilah fungsi untuk membantu Anda memulai dengan layanan Anda

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
6

Apakah ini ilustrasi nyata yang lengkap? . Saya akan bertaruh sedikit. ly melakukan hal-hal dengan cara yang sedikit lebih canggih daripada menyimpan tambang emasnya di kamus Python global yang tidak persisten di antara sesi

Catatan. Jika Anda ingin membuat pemendek URL lengkap milik Anda sendiri, periksa Buat Pemendek URL Dengan FastAPI dan Python

Namun, ini kira-kira akurat secara konseptual

>>> ________20______7

Tunggu. Satu hal yang mungkin Anda perhatikan adalah bahwa kedua hasil ini memiliki panjang 7 saat Anda meminta 5 byte. Tunggu, saya pikir Anda mengatakan hasilnya akan dua kali lebih lama? . Ada satu hal lagi yang terjadi di sini.

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_82 menggunakan pengkodean base64, di mana setiap karakter adalah 6 bit data. (Ini 0 hingga 63, dan karakter yang sesuai. Karakternya adalah A-Z, a-z, 0-9, dan +/. )

Jika Anda awalnya menentukan sejumlah byte

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
83, panjang yang dihasilkan dari
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
84 akan menjadi
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
85, yang dapat Anda buktikan dan selidiki lebih lanjut jika Anda penasaran

Intinya di sini adalah bahwa, sementara

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4 sebenarnya hanyalah pembungkus dari fungsi Python yang ada, ini bisa menjadi pilihan Anda saat keamanan menjadi perhatian utama Anda

Satu Kandidat Terakhir. >>> random.randint(0, 10) 7 >>> random.randint(500, 50000) 18601 _5

Satu opsi terakhir untuk menghasilkan token acak adalah fungsi

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
88 dari modul
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
5 Python. UUID adalah Pengidentifikasi Unik Universal, urutan 128-bit (
>>> random.uniform(20, 30)
27.42639687016509
>>> random.uniform(30, 40)
36.33865802745107
7 dengan panjang 32) yang dirancang untuk “menjamin keunikan melintasi ruang dan waktu. ”
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_88 adalah salah satu fungsi modul yang paling berguna, dan fungsi ini

>>> ________20______8

Hal yang menyenangkan adalah bahwa semua fungsi

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
_5 menghasilkan turunan dari kelas
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
94, yang merangkum ID dan memiliki properti seperti
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
95,
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
96, dan
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
97

>>> ________20______9

Anda mungkin juga telah melihat beberapa variasi lainnya.

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_98,
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
99, dan
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
00. Perbedaan utama antara ini dan
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_88 adalah bahwa ketiga fungsi tersebut semuanya mengambil beberapa bentuk input dan oleh karena itu tidak memenuhi definisi "acak" sejauh yang dilakukan UUID Versi 4

  • >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    _98 menggunakan ID host mesin Anda dan waktu saat ini secara default. Karena ketergantungan pada waktu saat ini hingga resolusi nanodetik, versi ini adalah tempat UUID memperoleh klaim “keunikan yang dijamin sepanjang waktu. ”

  • >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    >>> seed(1234)
    >>> [random() for _ in range(10)]
    [16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
    
    _99 dan
    >>> # Don't call `random.seed()` yet
    >>> import random
    >>> random.random()
    0.35553263284394376
    >>> random.random()
    0.6101992345575074
    
    00 keduanya mengambil pengidentifikasi namespace dan nama. Yang pertama menggunakan hash MD5 dan yang terakhir menggunakan SHA-1

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
_88, sebaliknya, sepenuhnya pseudorandom (atau acak). Ini terdiri dari mendapatkan 16 byte melalui
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
30, mengubahnya menjadi integer big-endian, dan melakukan sejumlah operasi bitwise untuk mematuhi

Mudah-mudahan, sekarang Anda sudah memiliki gagasan bagus tentang perbedaan antara berbagai “jenis” data acak dan cara membuatnya. Namun, satu masalah lain yang mungkin terlintas dalam pikiran adalah tabrakan

Dalam hal ini, tabrakan hanya merujuk pada pembuatan dua UUID yang cocok. Apa peluangnya? . ada

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
_07 atau 340 undecillion kemungkinan
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
08 nilai. Jadi, saya serahkan kepada Anda untuk menilai apakah ini cukup sebagai jaminan untuk tidur nyenyak

Salah satu penggunaan umum dari

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
5 adalah di Django, yang memiliki a yang sering digunakan sebagai kunci utama dalam basis data relasional yang mendasari model

Hilangkan iklan

Mengapa Tidak Hanya “Default to” ________20______11?

Selain modul aman yang dibahas di sini seperti

>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4, modul
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 Python sebenarnya memiliki kelas yang jarang digunakan bernama yang menggunakan
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
30. (
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
_11, pada gilirannya, juga digunakan oleh
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4. Itu semua adalah sedikit web yang menelusuri kembali ke
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
18. )

Pada titik ini, Anda mungkin bertanya pada diri sendiri mengapa Anda tidak "default ke" versi ini saja?

Saya sudah menyebutkan satu alasan. terkadang Anda ingin data Anda deterministik dan dapat direproduksi untuk diikuti orang lain

Tetapi alasan kedua adalah bahwa CSPRNG, setidaknya dengan Python, cenderung jauh lebih lambat daripada PRNG. Mari kita uji dengan skrip,

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
20, yang membandingkan versi PRNG dan CSPRNG dari
>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]

>>> seed(1234)
>>> [random() for _ in range(10)]
[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]
05 menggunakan
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
22 Python

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
0

Sekarang untuk menjalankan ini dari shell

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
_1

Perbedaan waktu 5x tentunya menjadi pertimbangan yang valid selain keamanan kriptografi saat memilih di antara keduanya

Barang sisa. Hashing

Salah satu konsep yang belum mendapat banyak perhatian dalam tutorial ini adalah hashing, yang dapat dilakukan dengan modul

>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
23 Python

Hash dirancang untuk menjadi pemetaan satu arah dari nilai input ke string ukuran tetap yang hampir tidak mungkin direkayasa balik. Dengan demikian, sementara hasil dari fungsi hash mungkin "terlihat seperti" data acak, itu tidak benar-benar memenuhi syarat di bawah definisi di sini

Rekap

Anda telah membahas banyak hal dalam tutorial ini. Sebagai rangkuman, berikut adalah perbandingan tingkat tinggi dari opsi yang tersedia bagi Anda untuk merekayasa keacakan dengan Python

Package/ModuleDescriptionCryptographically Secure

>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2Fasty & easy random data using Mersenne TwisterNo
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
2Like
>>> random.seed(444)
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987

>>> random.seed(444)  # Re-seed
>>> random.random()
0.3088946587429545
>>> random.random()
0.01323751590501987
2 but for (possibly multidimensional) arraysNo
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
3Contains
>>> # Don't call `random.seed()` yet
>>> import random
>>> random.random()
0.35553263284394376
>>> random.random()
0.6101992345575074
18, the base of other functions covered hereYes
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
4Designed to be Python's de facto module for generating secure random numbers, bytes, and stringsYes
>>> random.randint(0, 10)
7
>>> random.randint(500, 50000)
18601
5Home to a handful of functions for

Jangan ragu untuk meninggalkan beberapa komentar acak di bawah ini, dan terima kasih telah membaca

Tautan Tambahan

  • Acak. org menawarkan "angka acak yang sebenarnya kepada siapa pun di Internet" yang berasal dari kebisingan atmosfer
  • Bagian dari modul
    >>> random.seed(444)
    >>> random.random()
    0.3088946587429545
    >>> random.random()
    0.01323751590501987
    
    >>> random.seed(444)  # Re-seed
    >>> random.random()
    0.3088946587429545
    >>> random.random()
    0.01323751590501987
    
    _2 memiliki beberapa trik tambahan
  • Makalah mani di Mersienne Twister muncul pada tahun 1997, jika Anda menyukai hal semacam itu
  • Fungsi define untuk memilih secara acak dari himpunan kombinatorik, seperti dari kombinasi atau permutasi
  • mencakup berbagai generator sampel acak yang dapat digunakan untuk membangun kumpulan data buatan dengan ukuran dan kompleksitas yang terkontrol
  • Eli Bendersky menggali
    >>> random.randrange(1, 10)
    5
    
    _3 dalam artikelnya
  • Pengantar Konkrit untuk Probabilitas menggunakan Python dari Peter Norvig juga merupakan sumber yang komprehensif
  • Pustaka Pandas menyertakan a yang dapat digunakan untuk menyetel keadaan acak sementara
  • Dari Stack Overflow
    • Menghasilkan Tanggal Acak Dalam Rentang yang Diberikan
    • Cara Tercepat untuk Menghasilkan String Unik Seperti Acak dengan Panjang Acak
    • Cara Menggunakan
      >>> random.randrange(1, 10)
      5
      
      _9 pada Generator
    • Ganti Elemen Acak dalam Array NumPy
    • Mendapatkan Angka dari /dev/random dengan Python

Tandai sebagai Selesai

Tonton Sekarang Tutorial ini memiliki kursus video terkait yang dibuat oleh tim Real Python. Tonton bersama dengan tutorial tertulis untuk memperdalam pemahaman Anda. Menghasilkan Data Acak dengan Python

🐍 Trik Python 💌

Dapatkan Trik Python singkat & manis yang dikirim ke kotak masuk Anda setiap beberapa hari. Tidak pernah ada spam. Berhenti berlangganan kapan saja. Dikuratori oleh tim Real Python

Bagaimana cara kerja sampel acak python?

Kirimi Saya Trik Python »

Tentang Brad Solomon

Bagaimana cara kerja sampel acak python?
Bagaimana cara kerja sampel acak python?

Brad adalah seorang insinyur perangkat lunak dan anggota Tim Tutorial Python Sejati

» Lebih lanjut tentang Brad


Setiap tutorial di Real Python dibuat oleh tim pengembang sehingga memenuhi standar kualitas tinggi kami. Anggota tim yang mengerjakan tutorial ini adalah

Bagaimana cara kerja sampel acak python?

Adriana

Bagaimana cara kerja sampel acak python?

Geir Arne

Bagaimana cara kerja sampel acak python?

Joanna

Master Keterampilan Python Dunia Nyata Dengan Akses Tanpa Batas ke Python Nyata

Bergabunglah dengan kami dan dapatkan akses ke ribuan tutorial, kursus video langsung, dan komunitas pakar Pythonista

Tingkatkan Keterampilan Python Anda »

Guru Keterampilan Python Dunia Nyata
Dengan Akses Tak Terbatas ke Real Python

Bergabunglah dengan kami dan dapatkan akses ke ribuan tutorial, kursus video langsung, dan komunitas ahli Pythonista

Tingkatkan Keterampilan Python Anda »

Bagaimana menurutmu?

Nilai artikel ini

Tweet Bagikan Bagikan Email

Apa takeaway # 1 Anda atau hal favorit yang Anda pelajari?

Kiat Berkomentar. Komentar yang paling berguna adalah yang ditulis dengan tujuan belajar dari atau membantu siswa lain. dan dapatkan jawaban atas pertanyaan umum di portal dukungan kami

Bagaimana cara Python menghasilkan angka acak?

Untuk menghasilkan angka acak dengan Python, randint() function digunakan. Fungsi ini didefinisikan dalam modul acak.

Bagaimana cara kerja sampel di Python?

sample() adalah fungsi bawaan dari modul acak di Python yang mengembalikan daftar panjang tertentu dari item yang dipilih dari urutan i. e. daftar, tuple, string atau set . Digunakan untuk pengambilan sampel acak tanpa penggantian. Parameter. urutan. Bisa berupa list, tuple, string, atau set.

Bagaimana Anda memilih sampel acak dari populasi dengan Python?

Jika Anda mengambil sampel dari populasi individu yang datanya direpresentasikan dalam baris tabel, maka Anda dapat menggunakan sampel metode Tabel untuk memilih baris tabel secara acak. .
Secara default, sampel diambil secara acak secara acak dengan penggantian

Apakah Python acak benar-benar acak?

Sebagian besar data acak yang dihasilkan dengan Python tidak sepenuhnya acak dalam pengertian ilmiahnya . Sebaliknya, itu adalah pseudorandom. dihasilkan dengan pseudorandom number generator (PRNG), yang pada dasarnya adalah algoritma apa pun untuk menghasilkan data yang tampaknya acak tetapi masih dapat direproduksi.