Ответы:
Для этого нет встроенных средств, поэтому вам нужно использовать что-то внешнее.
/bin/sh
)Вызов:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
с system()
это хороший способ. Вы можете получить только цифры, заменив tr
на grep
:
strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15
Вы можете использовать это в Vim следующим образом:
:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15")
Число 15 - это количество чисел, которое вы хотите (скорректируйте соответственно). Это должно работать на Linux, BSD, OSX и других системах UNIX. Это не будет работать на MS Windows.
Также см. Мой пост в блоге « Генерация паролей из командной строки » (есть много плохих решений для этого там).
Ruby, вероятно, является следующим лучшим выбором, так как скрипты на Ruby кажутся немного более распространенными, чем скрипты на Python. Получить случайное число легко:
:ruby puts Random.rand(10)
Или получить 15 номеров:
:ruby 15.times { puts Random.rand(10) }
Вы можете использовать случайный модуль; чтобы получить один номер:
:py import random; print(random.randint(0, 9))
Или 15 номеров:
:py import random
:py for i in range(0, 15): print(random.randint(0, 9))
Это должно работать как для Python 2 и 3.
Вы можете использовать, Get-Random
чтобы получить случайное число:
:echo system('Get-Random')
cmd.exe
Windows 7 и более поздние версии должны поставляться с PowerShell, но если вы хотите максимальной совместимости, вы можете использовать cmd.exe
. У него есть специальная переменная %RANDOM%
:
:echo system('@echo %RANDOM%')
Примечание: это не очень случайно! , использует время (!)
Обратите внимание, что вам не нужно использовать привязки Ruby или Python для использования решений Ruby или Python; Вы также можете создать отдельный скрипт и вызывать их с помощью
system("python -c '...'")
(для этого, конечно, требуется установить ruby / python).
tr -d '[:space:]'
, возможно, tr -cd '[:digit:]'
для фильтра grep?
:r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom
генерировать 3 случайных целых числа со знаком.
:r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
Вот чистое решение vimscript . Я не создал его, он был разработан Чарльзом Э. Кэмпбеллом. Вы можете найти репозиторий Github с его кодом здесь .
Алгоритм использует 3 начальных числа, сгенерированных при запуске Vim, и генерирует псевдослучайное число на основе вычислений и перестановок, примененных к начальным значениям:
" 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
Область видимости переменных объявлена как глобальная, потому что они используются функцией генератора, но могут быть ограничены сценарием ( s:
)
А вот и функция генератора:
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
Репо включает в себя следующие функции:
Вот быстрый тест, который я написал для тестирования генератора: я сгенерировал 1000000 чисел от 0 до 9 и посчитал количество вхождений каждого числа, вот результаты:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
Как вы можете видеть, поколение, кажется, хорошо распределено. Я знаю, что этого недостаточно для тестирования генератора случайных чисел, поэтому я попытаюсь провести дополнительный анализ, если у меня будет немного свободного времени.
Этот метод найден в плагине vim-randomtag , который основан на чтении ... микросекунд текущего времени, который можно использовать, когда вам просто нужно какое-то число, вас не волнует качество случайности или проблемы с безопасностью и т. Д .:
function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
Vim не предлагает собственный генератор случайных чисел, однако если у вас есть vim, скомпилированный с Python, следующий метод добавит случайную цифру в конце вашей строки:
:py import vim, random; vim.current.line += str(random.randint(0, 9))
Примечание: чтобы проверить, поддерживает ли ваш vim Python, попробуйте: :echo has('python')
(1 для да).
Вы также можете использовать оболочку, которая предлагает $RANDOM
переменную (работает с bash / ksh / zsh), которая возвращает псевдослучайный (0-32767), например:
:r! echo $RANDOM
или:
:put =system('echo $RANDOM')
или:
:r! od -An -td -N1 /dev/urandom
В Windows вы должны установить Cygwin / MSYS / SUA или использовать %RANDOM%
переменную, как рекомендует Carpetsmoker .
Если у вас нет доступа к shell и Python, как в случае обходного пути, вы используете последние несколько цифр из текущей отметки времени, например:
:put =reltimestr(reltime())[-2:]
Примечание: если вы используете его довольно часто, напишите простую функцию, которая будет return reltimestr(reltime())[-4:]
.
Примечание. Указанные выше методы возвращают только псевдослучайное целое число, которое не следует использовать для генерации ключа шифрования.
Чтобы добавить больше случайных чисел, нажмите, @:чтобы повторить команду еще раз. Или префикс с номером (например 10@:), чтобы добавить гораздо больше случайных чисел, разделенных новыми строками.
Связанный:
zsh
, но не с sh
, dash
, fish
, csh
, или tcsh
... Вы можете использовать :r! bash -c 'echo $RANDOM'
...
GetRandom()
функцию, где хороший prng имеет значение, поэтому лучше, если это возможно, получить его с самого начала (а это почти всегда возможно!)
$RANDOM
, но если это плохой PRNG, то это не повод использовать еще более слабый PRNG :-) Вместо этого, обновите его до лучшего PRNG! Насколько я знаю, /dev/urandom
он доступен на всех платформах, где bash
он широко доступен, поэтому я не вижу причин не использовать его.
$RANDOM
. Похоже, очень хороший маленький инструмент, и, хотя это может быть "RNG бедного человека" (как указывает @Carpetsmoker), он определенно соответствует требованию @ kenorb (который задал вопрос) "легко запоминающимся".
Вы можете использовать rand()
и srand()
функцию, при условии , ваш Vim двоичный включает патч 8.1.2342 .
Например, для генерации 10 случайных чисел, разделенных символами новой строки:
let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")
Чтобы сгенерировать 10 случайных чисел, все уступающие 100:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
Чтобы сгенерировать 10 случайных алфавитных строк из 5 символов:
let seed = srand()
echo range(10)
\ ->map({-> range(5)
\ ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
\ ->join("\n")
Чтобы сгенерировать 10 случайных слов (взятых из файла словаря /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")
Для генерации 10 последовательностей из 5 случайных слов:
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")
Для генерации случайного UUID версии 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], '')
Чтобы применить случайную цветовую схему:
let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]
Я не думаю, что есть собственная функция для случайных чисел в Vimscript.
Способ использования :python
(используйте его в функции, возможно, с заменой 10000 и 60 параметрами):
: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
Смотрите мой ответ на Создание коробки в vim через python для краткого введения в скрипты Python в Vim.
Поскольку vim.current.buffer
это список строк, мы можем назначить ему список строк так же, как в Python. random.sample
это просто самый простой способ, которым я могу придумать, получить список случайных целых чисел в Python.
random.sample
восстанавливает только два аргумента в Python 2, str
это встроенная функция для преобразования вещей в строки. Позвольте мне посмотреть эквиваленты Py3 ( str
будет то же самое, придется проверить xrange
и random.sample
).
xrange
не в Python3, потому что range
это эквивалентно (ни один из них фактически не создает список, в отличие от range
Py2).
map
в Py3 возвращается итеративный, а не список, поэтому будет использоваться последняя строкаlist(map(str, random.sample(range(10000), 60)))
:python
?