Jawaban:
Tidak ada fasilitas bawaan untuk ini, jadi Anda harus menggunakan sesuatu yang eksternal.
/bin/sh
)Panggilan:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
dengan system()
adalah cara yang baik. Anda hanya bisa mendapatkan nomor dengan mengganti tr
dengan grep
:
strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15
Anda dapat menggunakan ini di Vim seperti:
:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15")
Angka 15 adalah jumlah angka yang Anda inginkan (sesuaikan sesuai). Ini harus bekerja pada Linux, BSD, OSX, dan sistem UNIX lainnya. Itu tidak akan berfungsi pada MS Windows.
Juga lihat posting weblog saya " Hasilkan kata sandi dari commandline " (ada banyak solusi buruk untuk ini di luar sana).
Ruby mungkin adalah pilihan terbaik berikutnya, karena scripting Ruby tampaknya sedikit lebih umum daripada scripting Python. Mendapatkan nomor acak itu mudah:
:ruby puts Random.rand(10)
Atau untuk mendapatkan 15 nomor:
:ruby 15.times { puts Random.rand(10) }
Anda dapat menggunakan modul acak ; untuk mendapatkan satu nomor:
:py import random; print(random.randint(0, 9))
Atau 15 angka:
:py import random
:py for i in range(0, 15): print(random.randint(0, 9))
Ini seharusnya bekerja untuk Python 2 & 3.
Anda dapat menggunakan Get-Random
untuk mendapatkan nomor acak:
:echo system('Get-Random')
cmd.exe
Windows 7 dan yang lebih baru harus dikirim dengan PowerShell, tetapi jika Anda ingin kompatibilitas maksimum Anda dapat menggunakan cmd.exe
. Ini memiliki variabel khusus %RANDOM%
:
:echo system('@echo %RANDOM%')
Catatan: Ini tidak terlalu acak! , ini menggunakan waktu (!)
Perhatikan bahwa Anda tidak perlu menggunakan ikatan Ruby atau Python untuk menggunakan solusi Ruby atau Python; Anda juga dapat membuat skrip terpisah dan memanggil mereka dengan
system("python -c '...'")
(ini memang mengharuskan ruby / python diinstal, jelas.
tr -d '[:space:]'
, mungkin tr -cd '[:digit:]'
untuk filter grep?
:r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom
, akan menghasilkan 3 bilangan bulat yang ditandatangani secara acak.
:r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
Berikut ini adalah solusi vimscript murni . Saya tidak membuatnya, ini dikembangkan oleh Charles E. Campbell. Anda dapat menemukan repo Github dengan kode-nya di sini .
Algoritme menggunakan 3 biji yang dihasilkan pada startup Vim dan menghasilkan angka pseudo-acak berdasarkan perhitungan dan permutasi yang diterapkan pada biji:
" Randomization Variables
" with a little extra randomized start from localtime()
let g:rndm_m1 = 32007779 + (localtime()%100 - 50)
let g:rndm_m2 = 23717810 + (localtime()/86400)%100
let g:rndm_m3 = 52636370 + (localtime()/3600)%100
Ruang lingkup variabel dinyatakan sebagai global karena mereka digunakan oleh fungsi generator tetapi bisa dibatasi untuk skrip ( s:
)
Dan di sini adalah fungsi generator:
function! Rndm()
let m4= g:rndm_m1 + g:rndm_m2 + g:rndm_m3
if( g:rndm_m2 < 50000000 )
let m4= m4 + 1357
endif
if( m4 >= 100000000 )
let m4= m4 - 100000000
if( m4 >= 100000000 )
let m4= m4 - 100000000
endif
endif
let g:rndm_m1 = g:rndm_m2
let g:rndm_m2 = g:rndm_m3
let g:rndm_m3 = m4
return g:rndm_m3
endfun
Repo mencakup fungsi-fungsi berikut:
Berikut ini adalah tes cepat yang saya tulis untuk menguji generator: Saya menghasilkan 10.00000 angka antara 0 dan 9 dan menghitung jumlah kemunculan setiap angka di sini adalah hasilnya:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
Seperti yang Anda lihat, generasi tampaknya terdistribusi dengan baik. Saya sadar bahwa ini sebagian besar tidak cukup untuk menguji generator acak jadi saya akan mencoba membuat beberapa analisis tambahan jika saya punya waktu luang.
Ini adalah metode yang ditemukan dalam plugin vim-randomtag , yang didasarkan pada pembacaan ... mikrodetik waktu saat ini, dapat digunakan ketika Anda hanya menginginkan beberapa nomor, Anda tidak terlalu peduli tentang kualitas keacakan, atau memiliki masalah keamanan dll .:
function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
Vim tidak menawarkan generator acak asli, namun jika Anda memiliki vim yang dikompilasi dengan Python, metode berikut ini akan menambahkan digit acak di akhir baris Anda:
:py import vim, random; vim.current.line += str(random.randint(0, 9))
Catatan: Untuk memeriksa apakah vim Anda mendukung Python, coba: :echo has('python')
(1 untuk ya).
Anda juga dapat menggunakan shell yang menawarkan $RANDOM
variabel (berfungsi dengan bash / ksh / zsh) yang mengembalikan pseudorandom (0-32767), misalnya:
:r! echo $RANDOM
atau:
:put =system('echo $RANDOM')
atau:
:r! od -An -td -N1 /dev/urandom
Di Windows, Anda harus menginstal Cygwin / MSYS / SUA, atau menggunakan %RANDOM%
variabel seperti yang disarankan Carpetsmoker .
Jika Anda tidak memiliki akses ke shell dan Python, seperti untuk penyelesaiannya, Anda menggunakan beberapa digit terakhir dari cap waktu saat ini, misalnya:
:put =reltimestr(reltime())[-2:]
Catatan: Jika Anda cukup sering menggunakannya, tulislah fungsi sederhana yang akan return reltimestr(reltime())[-4:]
.
Catatan: Metode di atas hanya mengembalikan integer pseudorandom yang tidak boleh digunakan untuk menghasilkan kunci enkripsi.
Untuk menambahkan lebih banyak angka acak, silakan tekan @:untuk mengulangi perintah lagi. Atau awalan dengan angka (seperti 10@:) untuk menambahkan lebih banyak angka acak yang dipisahkan oleh baris baru.
Terkait:
zsh
, tetapi tidak dengan sh
, dash
, fish
, csh
, atau tcsh
... Anda bisa menggunakan :r! bash -c 'echo $RANDOM'
...
GetRandom()
fungsi Anda di mana prng yang baik itu penting, jadi lebih baik untuk melakukannya dengan benar dari awal jika memungkinkan (dan hampir selalu memungkinkan di sini!)
$RANDOM
, tetapi jika ini adalah PRNG yang buruk maka itu bukan alasan untuk menggunakan PRNG yang lebih buruk :-) Sebaliknya, tingkatkan ke PRNG yang lebih baik! Sejauh yang saya tahu, /dev/urandom
tersedia di semua platform di mana bash
biasanya tersedia, jadi saya tidak melihat alasan untuk tidak menggunakannya.
$RANDOM
. Sepertinya alat kecil yang sangat bagus, dan meskipun itu mungkin "orang miskin RNG" (seperti yang ditunjukkan oleh @Carpetsmoker), itu pasti cocok dengan persyaratan @ kenorb (yang mengajukan pertanyaan) persyaratan "mudah diingat".
Anda dapat menggunakan rand()
dan srand()
fungsinya, asalkan biner Vim Anda menyertakan tambalan 8.1.2342 .
Sebagai contoh, untuk menghasilkan 10 angka acak yang dipisahkan oleh baris baru:
let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")
Untuk menghasilkan 10 angka acak, semua lebih rendah dari 100:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
Untuk menghasilkan 10 string alfabet acak dengan 5 karakter:
let seed = srand()
echo range(10)
\ ->map({-> range(5)
\ ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
\ ->join("\n")
Untuk menghasilkan 10 kata acak (diambil dari file kamus /usr/share/dict/words
):
let seed = srand()
let words = readfile('/usr/share/dict/words')
let len = len(words)
echo range(10)->map({-> g:words[rand(g:seed) % g:len]})->join("\n")
Untuk menghasilkan 10 urutan 5 kata acak:
let seed = srand()
let words = readfile('/usr/share/dict/words')
let len = len(words)
echo range(10)
\ ->map({-> range(5)
\ ->map({-> g:words[rand(g:seed) % g:len]})->join()})
\ ->join("\n")
Untuk menghasilkan UUID versi 4 acak:
" Based on this answer: /programming//a/38191078/9780968
let seed = srand()
let random_numbers = range(30)->map({-> rand(g:seed) % 16})
echo call('printf', ['%x%x%x%x%x%x%x%x-%x%x%x%x-4%x%x%x'] + random_numbers[:14])
\ ..call('printf', ['-X%x%x%x-%x%x%x%x%x%x%x%x%x%x%x%x'] + random_numbers[15:])
\ ->substitute('X', '89ab'[rand(seed) % 4], '')
Untuk menerapkan skema warna acak:
let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]
Saya tidak berpikir ada fungsi asli untuk angka acak di Vimscript.
Cara menggunakan :python
(menggunakannya dalam suatu fungsi, mungkin, dengan 10000 dan 60 diganti dengan parameter):
:python <<EOF
import vim
import random
line = vim.current.window.cursor[0]
r = getattr(__builtins__, 'xrange', range) # To make it work for both Python 2 & 3
vim.current.buffer[line:line] = list(map(str, random.sample(r(10000), 60)))
EOF
Lihat jawaban saya untuk Membuat kotak dalam vim melalui python untuk intro cepat tentang skrip Python di Vim.
Karena vim.current.buffer
ini adalah daftar string, kita bisa menetapkan daftar string seperti yang kita lakukan dengan Python. random.sample
hanyalah cara paling sederhana yang dapat saya pikirkan untuk mendapatkan daftar bilangan bulat acak dengan Python.
random.sample
hanya mengulangi dua argumen pada Python 2, str
adalah fungsi bawaan untuk mengubah berbagai hal menjadi string. Biarkan saya mencari yang setara dengan Py3 ( str
akan sama, harus memeriksa xrange
dan random.sample
).
xrange
tidak dalam Python3 karena range
sama (tidak benar-benar membangun daftar, tidak seperti range
dalam Py2).
map
dalam Py3 mengembalikan iterable dan bukan daftar, jadi baris terakhir akan menggunakanlist(map(str, random.sample(range(10000), 60)))
:python
?