Risposte:
Non esiste una funzione integrata per questo, quindi dovrai usare qualcosa di esterno.
/bin/sh
)Calling:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
con system()
è un buon modo. Puoi ottenere solo numeri sostituendo tr
con grep
:
strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15
Puoi usarlo in Vim in questo modo:
:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15")
Il numero 15 è la quantità di numeri che si desidera (regolare di conseguenza). Questo dovrebbe funzionare su Linux, BSD, OSX e altri sistemi UNIX. Non funzionerà su MS Windows.
Vedi anche il mio post sul blog " Genera password dalla riga di comando " (ci sono molte cattive soluzioni per questo là fuori).
Ruby è probabilmente la scelta migliore successiva, dal momento che lo scripting Ruby sembra essere un po 'più comune dello scripting Python. Ottenere un numero casuale è facile:
:ruby puts Random.rand(10)
O per ottenere 15 numeri:
:ruby 15.times { puts Random.rand(10) }
Puoi usare il modulo casuale ; per ottenere un singolo numero:
:py import random; print(random.randint(0, 9))
O un 15 numeri:
:py import random
:py for i in range(0, 15): print(random.randint(0, 9))
Questo dovrebbe funzionare sia per Python 2 che per 3.
Puoi usare Get-Random
per ottenere un numero casuale:
:echo system('Get-Random')
cmd.exe
Windows 7 e versioni successive dovrebbero essere forniti con PowerShell, ma se si desidera la massima compatibilità è possibile utilizzare cmd.exe
. Ha una variabile speciale %RANDOM%
:
:echo system('@echo %RANDOM%')
Nota: questo non è molto casuale! , usa il tempo (!)
Si noti che non è necessario utilizzare i collegamenti Ruby o Python per utilizzare le soluzioni Ruby o Python; potresti anche creare uno script separato e chiamarli con
system("python -c '...'")
(questo richiede che ruby / python sia installato, ovviamente.
tr -d '[:space:]'
, forse tr -cd '[:digit:]'
per il filtro grep?
:r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom
generare 3 numeri casuali con segno.
:r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
Ecco una pura soluzione vimscript . Non l'ho creato, è stato sviluppato da Charles E. Campbell. Puoi trovare un repository Github con il suo codice qui .
L'algoritmo utilizza 3 seed generati all'avvio di Vim e genera un numero pseudo-casuale basato su calcoli e permutazioni applicati ai seed:
" 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
L'ambito delle variabili è dichiarato globale perché vengono utilizzati dalla funzione generatore ma potrebbe essere limitato allo script ( s:
)
Ed ecco la funzione del generatore:
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
Il repository include le seguenti funzioni:
Ecco un breve test che ho scritto per testare il generatore: ho generato 1000000 numeri tra 0 e 9 e ho contato il numero di occorrenze di ciascun numero qui sono i risultati:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
Come puoi vedere, la generazione sembra essere ben distribuita. Sono consapevole che questo non è in gran parte sufficiente per testare un generatore casuale quindi proverò a fare qualche analisi extra se avrò del tempo libero.
Questo è un metodo che si trova nel plug -in vim-randomtag , che si basa sulla lettura ... microsecondi dell'ora corrente, utilizzabili quando si desidera solo un numero, non ci si preoccupa molto della qualità della casualità o si hanno problemi di sicurezza ecc .:
function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
Vim non offre un generatore casuale nativo, tuttavia se hai compilato Vim con Python, il seguente metodo aggiungerà una cifra casuale alla fine della riga:
:py import vim, random; vim.current.line += str(random.randint(0, 9))
Nota: per verificare se Vim supporta Python, provare: :echo has('python')
(1 per Sì).
Puoi anche usare la shell che offre $RANDOM
variabili (funziona con bash / ksh / zsh) che restituisce uno pseudocasuale (0-32767), ad esempio:
:r! echo $RANDOM
o:
:put =system('echo $RANDOM')
o:
:r! od -An -td -N1 /dev/urandom
Su Windows, devi avere Cygwin / MSYS / SUA installato o usare la %RANDOM%
variabile come suggerito da Carpetsmoker .
Se non hai accesso a shell e Python, come per la soluzione alternativa, usi le ultime cifre del timestamp corrente, ad esempio:
:put =reltimestr(reltime())[-2:]
Nota: se lo usi abbastanza spesso, scrivi una semplice funzione che lo farà return reltimestr(reltime())[-4:]
.
Nota: i metodi sopra riportati restituiscono solo un numero intero pseudocasuale che non deve essere utilizzato per generare una chiave di crittografia.
Per aggiungere più numeri casuali, premere @:per ripetere nuovamente il comando. Oppure 10@:aggiungi il prefisso con il numero (come ) per aggiungere molti più numeri casuali separati da nuove righe.
Relazionato:
zsh
, ma non con sh
, dash
, fish
, csh
, o tcsh
... Si potrebbe usare :r! bash -c 'echo $RANDOM'
...
GetRandom()
funzione di dove il buon PRNG fa importa, quindi è meglio per ottenere solo che fin dall'inizio, se possibile (ed è quasi sempre possibile qui!)
$RANDOM
, ma se si tratta di un PRNG scadente, non è un motivo per utilizzare un PRNG ancora più povero :-) Invece, passare a un PRNG migliore! Per quanto ne so, /dev/urandom
è disponibile su tutte le piattaforme in cui bash
è comunemente disponibile, quindi non vedo un motivo per non usarlo.
$RANDOM
. Sembra un piccolo strumento molto carino, e anche se può essere un "povero RNG" (come sottolinea @Carpetsmoker), si adatta sicuramente al requisito di @ kenorb (che ha posto la domanda) di "facilmente memorabile".
Puoi usare le funzioni rand()
e srand()
, a condizione che il tuo binario Vim includa la patch 8.1.2342 .
Ad esempio, per generare 10 numeri casuali separati da newline:
let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")
Per generare 10 numeri casuali tutti inferiori a 100:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
Per generare 10 stringhe alfabetiche casuali di 5 caratteri:
let seed = srand()
echo range(10)
\ ->map({-> range(5)
\ ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
\ ->join("\n")
Per generare 10 parole casuali (prese dal file del dizionario /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")
Per generare 10 sequenze di 5 parole casuali:
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")
Per generare una versione UUID casuale 4:
" 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], '')
Per applicare una combinazione di colori casuale:
let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]
Non credo che ci sia una funzione nativa per numeri casuali in Vimscript.
Un modo usando :python
(usalo in una funzione, forse, con 10000 e 60 sostituiti da parametri):
: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
Vedi la mia risposta a Making a box in vim via python per una rapida introduzione sullo scripting Python in Vim.
Dato che vim.current.buffer
è un elenco di stringhe, possiamo assegnargli un elenco come faremmo in Python. random.sample
è solo il modo più semplice che mi viene in mente di ottenere un elenco di numeri interi casuali in Python.
random.sample
riproduce solo due argomenti su Python 2, str
è la funzione integrata per convertire le cose in stringhe. Vorrei cercare gli equivalenti Py3 ( str
sarebbe lo stesso, dovrà controllare xrange
e random.sample
).
xrange
non è in Python3 perché range
è equivalente (né costruisce effettivamente un elenco, a differenza range
di Py2).
map
in Py3 restituisce un iterabile e non un elenco, quindi l'ultima riga userebbelist(map(str, random.sample(range(10000), 60)))
:python
?