Відповіді:
Для цього немає вбудованого засобу, тому вам потрібно буде використовувати щось зовнішнє.
/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.
Також дивіться мій пост у веб-журналі " Створення паролів з командного рядка " (для цього існує маса поганих рішень).
Рубі, мабуть, наступний найкращий вибір, оскільки сценарії Рубі здаються дещо частішими, ніж сценарії 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 '...'")
(очевидно, для цього потрібно встановити рубін / пітон.
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
Ось чисте вимскриптне рішення. Я його не створив, його розробив Чарльз Е. Кемпбелл. Ви можете знайти репо 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 .
Якщо у вас немає доступу до оболонки та Python, як для вирішення проблеми, ви використовуєте останні кілька цифр з поточної мітки часу, наприклад:
:put =reltimestr(reltime())[-2:]
Примітка. Якщо ви використовуєте його досить часто, напишіть просту функцію, яка буде return reltimestr(reltime())[-4:]
.
Примітка. Вищезазначені методи повертають лише псевдовипадкове ціле число, яке не слід використовувати для створення ключа шифрування.
Щоб додати більше випадкових чисел, натисніть, @:щоб повторити команду ще раз. Або префікс з числом (як 10@:), щоб додати набагато більше випадкових чисел, розділених новими рядками.
Пов'язані:
zsh
, але не з sh
, dash
, fish
, csh
, або tcsh
... Ви можете використовувати :r! bash -c 'echo $RANDOM'
...
GetRandom()
функцію там, де має значення хороший прнґ , тому краще просто отримати це з самого початку, якщо це можливо (і це майже завжди можливо тут!)
$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
?