Pernyataan cetak berikut akan mencetak "hello world". Adakah yang bisa menjelaskan ini?
System.out.println(randomString(-229985452) + " " + randomString(-147909649));
Dan randomString()
terlihat seperti ini:
public static String randomString(int i)
{
Random ran = new Random(i);
StringBuilder sb = new StringBuilder();
while (true)
{
int k = ran.nextInt(27);
if (k == 0)
break;
sb.append((char)('`' + k));
}
return sb.toString();
}
n
difor (int n = 0; ; n++)
. Mereka bisa menggunakanfor(;;)
atauwhile(true)
sebagai gantinya!Jawaban:
Ketika sebuah instance
java.util.Random
dibangun dengan parameter seed tertentu (dalam kasus ini-229985452
atau-147909649
), ia mengikuti algoritma pembuatan bilangan acak yang dimulai dengan nilai seed tersebut.Setiap
Random
dibangun dengan benih yang sama akan menghasilkan pola angka yang sama setiap kali.sumber
"hello\0"
dan"world\0"
. Jika Anda mengasumsikan generator yang benar-benar acak, kemungkinannya adalah 1 dari 27 ^ 6 (387.420.489) untuk mendapatkan urutan yang Anda cari - jadi itu cukup mengesankan tetapi tidak terlalu mengejutkan!"Hello"
"World"
), atau menggunakan122-k
sebagai ganti96+k
, atau ...Jawaban lain menjelaskan mengapa, tapi begini caranya.
Diberikan contoh
Random
:6 angka pertama yang
r.nextInt(27)
menghasilkan adalah:dan 6 angka pertama yang
r.nextInt(27)
menghasilkan diberikanRandom r = new Random(-147909649)
adalah:Kemudian tambahkan saja angka-angka itu ke representasi integer karakter
`
(yaitu 96):sumber
new Random(-229985452).nextInt(27)
selalu mengembalikan 8.new Random()
tidak mengembalikan nomor sama sekali.Random
tidak aman secara kriptografis (saya cukup yakin itu adalah Twister Mersenne, tapi jangan mengutip saya tentang itu), mungkin mungkin untuk bekerja mundur dari "Saya ingin angka-angka ini" ke "ini adalah benih yang akan saya gunakan ". Saya telah melakukan sesuatu yang mirip dengan generator congruential C linear standar.Saya hanya akan meninggalkannya di sini. Siapa pun yang memiliki banyak waktu (CPU), jangan ragu untuk bereksperimen :) Juga, jika Anda telah menguasai beberapa fork-join-fu untuk membuat benda ini membakar semua core CPU (hanya utas yang membosankan, kan?), Silakan bagikan kode Anda. Saya akan sangat menghargainya.
Keluaran:
sumber
nextInt(27)
berarti dalam jangkauan[0, 26]
.Semua orang di sini melakukan pekerjaan yang luar biasa untuk menjelaskan cara kerja kode dan menunjukkan bagaimana Anda dapat membangun contoh Anda sendiri, tetapi inilah jawaban teoretis informasi yang menunjukkan mengapa kita dapat mengharapkan solusi yang ada sehingga pencarian brute force pada akhirnya akan ditemukan.
26 huruf kecil yang berbeda membentuk alfabet kami
Σ
. Untuk memungkinkan menghasilkan kata dengan panjang yang berbeda, kami selanjutnya menambahkan simbol terminator⊥
untuk menghasilkan alfabet yang diperluasΣ' := Σ ∪ {⊥}
.Membiarkan
α
menjadi simbol dan X variabel acak terdistribusi secara seragam berakhirΣ'
. Peluang untuk memperoleh simbol ituP(X = α)
, dan konten informasinyaI(α)
, diberikan oleh:Untuk satu kata
ω ∈ Σ*
dan⊥-
mitra yang diberhentikanω' := ω · ⊥ ∈ (Σ')*
, kami punyaKarena Pseudorandom Number Generator (PRNG) diinisialisasi dengan seed 32-bit, kita dapat mengharapkan sebagian besar kata panjang hingga
untuk dihasilkan oleh setidaknya satu biji. Bahkan jika kita mencari kata 6-karakter, kita masih akan berhasil sekitar 41,06% dari waktu. Tidak terlalu buruk.
Untuk 7 huruf kami melihat mendekati 1,52%, tetapi saya tidak menyadarinya sebelum mencobanya:
Lihat hasilnya: http://ideone.com/JRGb3l
sumber
I(⍵)
persamaan yang disusun ulang.I(⍵)
adalah 32 (bit) dan|⍵|
ternyata menjadi 5 (simbol).Saya menulis program cepat untuk menemukan benih ini:
Saya menjalankannya di latar belakang sekarang, tetapi sudah menemukan cukup kata untuk pangram klasik:
( Demo di ideone. )
Ps.
-727295876, -128911, -1611659, -235516779
.sumber
Saya tertarik dengan ini, saya menjalankan generator kata acak ini pada daftar kata kamus. Rentang: Integer.MIN_VALUE ke Integer.MAX_VALUE
Saya mendapat 15.131 hit.
Cetakan
sumber
Faktanya, kebanyakan generator angka acak adalah "pseudo random." Mereka adalah Linear Congruential Generator, atau LCGs ( http://en.wikipedia.org/wiki/Linear_congruential_generator )
LCG cukup dapat diprediksi karena memiliki benih yang tetap. Pada dasarnya, gunakan seed yang memberi Anda surat pertama Anda, kemudian tulis aplikasi yang terus menghasilkan int (char) berikutnya hingga Anda menekan huruf berikutnya dalam string target Anda dan tulis berapa kali Anda harus menggunakan LCG. Lanjutkan sampai Anda membuat setiap huruf.
sumber
/dev/urandom
perangkat untuk membaca data acak. Namun, ini adalah sumber daya yang langka. Jadi, data acak tersebut biasanya digunakan untuk menaburkan PRNG.urandom
masih pseudo random en.wikipedia.org/wiki//dev/random/dev/random
. Artikel yang saya kutip di atas mengatakan bahwa Kernel Linux menghasilkan entropi dari pengaturan waktu keyboard, pergerakan mouse, dan pengaturan waktu IDE dan membuat data karakter acak tersedia untuk proses sistem operasi lain melalui file khusus / dev / random dan / dev / urandom. Itu membuat saya percaya itu benar-benar acak. Mungkin itu tidak sepenuhnya benar. Tetapi/dev/random
setidaknya mengandung beberapa entropi.Karena multi-threading sangat mudah dengan Java, berikut adalah varian yang mencari seed menggunakan semua core yang tersedia: http://ideone.com/ROhmTA
sumber
L
dan ubah tipe argumen menjadilong
, yaiturandomString(long i)
untuk bermain-main. :)Acak selalu mengembalikan urutan yang sama. Ini digunakan untuk mengocok array dan operasi lainnya sebagai permutasi.
Untuk mendapatkan urutan yang berbeda, perlu menginisialisasi urutan di beberapa posisi, yang disebut "seed".
RandomSting mendapatkan nomor acak di posisi i (seed = -229985452) dari urutan "acak". Kemudian gunakan kode ASCII untuk 27 karakter berikutnya dalam urutan setelah posisi seed sampai nilai ini sama dengan 0. Ini mengembalikan "halo". Operasi yang sama dilakukan untuk "dunia".
Saya pikir kode itu tidak berfungsi untuk kata lain. Orang yang diprogram yang mengetahui urutan acak dengan sangat baik.
Ini kode geek yang sangat hebat!
sumber
Prinsipnya adalah Kelas Acak dibangun dengan benih yang sama akan menghasilkan pola angka yang sama setiap kali.
sumber
Berasal dari jawaban Denis Tulskiy , metode ini menghasilkan benih.
sumber
Dari dokumen Java, ini adalah fitur yang disengaja ketika menentukan nilai seed untuk kelas Random.
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html
Anehnya, Anda akan berpikir ada masalah keamanan implisit dalam memiliki nomor 'acak' yang dapat diprediksi.
sumber
Random
"menetapkan seed dari generator angka acak ke nilai yang sangat mungkin berbeda dari permintaan lain dari konstruktor ini" ( javadoc ). Dalam implementasi saat ini, ini adalah kombinasi dari waktu saat ini dan penghitung.Ini tentang "benih". Biji yang sama memberikan hasil yang sama.
sumber
Berikut ini adalah perbaikan kecil untuk jawaban Denis Tulskiy . Itu memotong waktu setengah
sumber
Keluaran
sumber