Odpowiedzi:
Nie ma do tego wbudowanej funkcji, więc musisz użyć czegoś zewnętrznego.
/bin/sh
)Powołanie:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
z system()
jest dobrym sposobem. Możesz uzyskać tylko liczby, zastępując tr
je grep
:
strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15
Możesz użyć tego w Vimie tak:
:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15")
Liczba 15 to liczba liczb, które chcesz (odpowiednio dostosuj). Powinno to działać w systemach Linux, BSD, OSX i innych systemach UNIX. To nie będzie działać na MS Windows.
Zobacz także mój post na blogu „ Generuj hasła z wiersza poleceń ” (istnieje wiele złych rozwiązań tego problemu).
Ruby jest prawdopodobnie najlepszym wyborem, ponieważ skrypty Ruby wydają się być nieco bardziej popularne niż skrypty w języku Python. Uzyskanie losowej liczby jest łatwe:
:ruby puts Random.rand(10)
Lub zdobyć 15 numerów:
:ruby 15.times { puts Random.rand(10) }
Możesz użyć losowego modułu; aby uzyskać pojedynczy numer:
:py import random; print(random.randint(0, 9))
Lub 15 liczb:
:py import random
:py for i in range(0, 15): print(random.randint(0, 9))
Powinno to działać zarówno w Pythonie 2, jak i 3.
Możesz użyć, Get-Random
aby uzyskać losową liczbę:
:echo system('Get-Random')
cmd.exe
Windows 7 i nowsze wersje powinny być dostarczane z programem PowerShell, ale jeśli chcesz uzyskać maksymalną kompatybilność, możesz użyć cmd.exe
. Ma specjalną zmienną %RANDOM%
:
:echo system('@echo %RANDOM%')
Uwaga: To nie jest bardzo losowe! , wykorzystuje czas (!)
Zauważ, że nie musisz używać powiązań Ruby lub Python, aby korzystać z rozwiązań Ruby lub Python; możesz także utworzyć osobny skrypt i wywołać go za pomocą
system("python -c '...'")
(oczywiście wymaga to zainstalowania Ruby / Pythona.
tr -d '[:space:]'
, może tr -cd '[:digit:]'
dla filtra grep?
:r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom
Wygenerowałby 3 liczby całkowite ze znakiem losowym .
:r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
Oto czyste rozwiązanie vimscript . Nie stworzyłem go, opracował go Charles E. Campbell. Można znaleźć repo GitHub z jego kod tutaj .
Algorytm wykorzystuje 3 nasiona wygenerowane przy starcie Vima i generuje pseudolosową liczbę na podstawie obliczeń i permutacji zastosowanych do nasion:
" 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
Zakres zmiennych jest zadeklarowany jako globalny, ponieważ są używane przez funkcję generatora, ale może być ograniczony do skryptu ( s:
)
A oto funkcja generatora:
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
Repozytorium obejmuje następujące funkcje:
Oto szybki test, który napisałem, aby przetestować generator: Wygenerowałem 1000000 liczb od 0 do 9 i policzyłem liczbę wystąpień każdej liczby tutaj są wyniki:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
Jak widać, generacja wydaje się być dobrze rozproszona. Zdaję sobie sprawę, że w dużej mierze nie wystarcza to do przetestowania generatora losowego, więc spróbuję przeprowadzić dodatkową analizę, jeśli będę miał trochę wolnego czasu.
Jest to metoda znaleźć w vim-randomtag wtyczki, która jest oparta na czytanie ... aktualne w czasie mikrosekund, użyteczny gdy chcesz po prostu jakiś numer, nie przejmował się przypadkowości jakości lub wątpliwości związanych z bezpieczeństwem itp .:
function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
Vim nie oferuje natywnego generatora losowego, jednak jeśli kompilujesz vima z Pythonem, następująca metoda doda losową cyfrę na końcu twojej linii:
:py import vim, random; vim.current.line += str(random.randint(0, 9))
Uwaga: Aby sprawdzić, czy Twój vim obsługuje Python, spróbuj: :echo has('python')
(1 na yes).
Możesz także użyć powłoki, która oferuje $RANDOM
zmienną (działa z bash / ksh / zsh), która zwraca pseudolosowy (0-32767), na przykład:
:r! echo $RANDOM
lub:
:put =system('echo $RANDOM')
lub:
:r! od -An -td -N1 /dev/urandom
W systemie Windows musisz mieć zainstalowany Cygwin / MSYS / SUA lub użyć %RANDOM%
zmiennej, jak sugeruje Carpetsmoker .
Jeśli nie masz dostępu do powłoki i Pythona, tak jak w celu obejścia tego problemu, użyj kilku ostatnich cyfr z bieżącego znacznika czasu, na przykład:
:put =reltimestr(reltime())[-2:]
Uwaga: Jeśli używasz go dość często, napisz prostą funkcję, która będzie return reltimestr(reltime())[-4:]
.
Uwaga: Powyższe metody zwracają tylko pseudolosowe liczby całkowite, których nie należy używać do generowania klucza szyfrowania.
Aby dodać więcej liczb losowych, naciśnij, @:aby powtórzyć polecenie ponownie. Lub przedrostek z liczbą (podobną 10@:), aby dodać znacznie więcej liczb losowych oddzielonych nowymi wierszami.
Związane z:
zsh
, ale nie z sh
, dash
, fish
, csh
, lub tcsh
... można użyć :r! bash -c 'echo $RANDOM'
...
GetRandom()
funkcji gdzie dobry PRNG robi sprawa, więc lepiej po prostu zrobić to dobrze od samego początku, jeśli to możliwe (i to prawie zawsze możliwe tutaj!)
$RANDOM
, ale jeśli jest to zły PRNG, to nie jest powód, aby używać jeszcze gorszego PRNG :-) Zamiast tego, uaktualnij do lepszego PRNG! O ile mi wiadomo, /dev/urandom
jest dostępny na wszystkich platformach, na których bash
jest powszechnie dostępny, więc nie widzę powodu, aby go nie używać.
$RANDOM
. Wydaje się, że jest to bardzo miłe, małe narzędzie i chociaż może to być „biedny człowiek RNG” (jak wskazuje @Carpetsmoker), zdecydowanie pasuje do wymagania @ kenorb (który zadał pytanie) „łatwej do zapamiętania”.
Możesz używać funkcji rand()
i srand()
, pod warunkiem, że twój plik binarny Vim zawiera łatkę 8.1.2342 .
Na przykład, aby wygenerować 10 liczb losowych oddzielonych znakami nowej linii:
let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")
Aby wygenerować 10 liczb losowych o wartości mniejszej niż 100:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
Aby wygenerować 10 losowych ciągów alfabetycznych po 5 znaków:
let seed = srand()
echo range(10)
\ ->map({-> range(5)
\ ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
\ ->join("\n")
Aby wygenerować 10 losowych słów (wziętych z pliku słownika /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")
Aby wygenerować 10 sekwencji 5 losowych słów:
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")
Aby wygenerować losowy UUID w wersji 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], '')
Aby zastosować losowy schemat kolorów:
let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]
Nie sądzę, żeby w Vimscript była natywna funkcja dla liczb losowych.
Sposób użycia :python
(użyj go w funkcji, być może z 10000 i 60 zastąpionymi parametrami):
: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
Zobacz moją odpowiedź na temat tworzenia skrzynki w vimie przez Pythona, aby uzyskać szybkie wprowadzenie do skryptów Pythona w Vimie.
Ponieważ vim.current.buffer
jest to lista ciągów, możemy przypisać do niej listę ciągów tak, jak w Pythonie. random.sample
to po prostu najprostszy sposób na uzyskanie listy losowych liczb całkowitych w Pythonie.
random.sample
naprawia tylko dwa argumenty w Pythonie 2, str
jest wbudowaną funkcją do konwersji rzeczy na ciągi. Pozwól, że sprawdzę ekwiwalenty Py3 ( str
byłoby to samo, będę musiał sprawdzić xrange
i random.sample
).
xrange
Nawias po 60 powinien być po 10000. Nie ma go w Python3, ponieważ range
jest równoważny (w rzeczywistości żaden nie tworzy listy, w przeciwieństwie range
do Py2).
map
w Py3 zwraca iterowalną, a nie listę, więc użyje ostatniej liniilist(map(str, random.sample(range(10000), 60)))
:python
?