如何做到这一点?
#1 楼
从Vim 8.1.2342开始,您可以使用rand()
和srand()
函数。这里是一个示例:
let g:seed = srand()
echo rand(g:seed) % 100 " to echo a random number between 0-99
对于较旧的Vims,您必须回过头来调用一些外部命令(如果启用了Vim,则使用Python,Perl,Tcl,MzScheme,Ruby,Lua语言接口)。
UNIX Shell(
/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是可能是下一个最佳选择,因为Ruby脚本似乎比Python脚本更常见。获得随机数很容易:
:ruby puts Random.rand(10)
或获得15个数字:
:ruby 15.times { puts Random.rand(10) }
Python
您可以使用random模块;以获得一个数字:
: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均适用。
Windows PowerShell
可以使用
Get-Random
:echo system('Get-Random')
Windows
cmd.exe
Windows 7和更高版本应随PowerShell一起提供,但如果要最大化
兼容性可以使用
cmd.exe
。它有一个特殊的变量%RANDOM%
::echo system('@echo %RANDOM%')
注意:这不是很随机!
,它使用时间(!)需要使用Ruby或Python绑定才能使用Ruby或
Python解决方案;您还可以创建一个单独的脚本,并使用
system("python -c '...'")
进行调用(显然,这确实需要安装ruby / python,。
评论
代替tr -d'[:space:]',也许是grep过滤器使用tr -cd'[:digit:]'吗?
–muru
2015年2月14日在23:33
@muru我不确定在OSX上是否可以使用,这就是为什么我不使用它的原因...您还以这种方式用换行符分隔了数字,就像OP要求的...。
–马丁·图尔诺伊(Martin Tournoij)
2015年2月14日在23:35
如果真是这样... GNU击败了BSD。 :P
–muru
2015年2月14日在23:36
也可以使用shell(系统)输入随机数,即:r! hexdump -n $(((3 * 4))-e'“%d”'/ dev / urandom,将生成3个随机有符号整数。
– HAL 9001
15年2月15日在7:13
@kenorb这将正确使用shell输入3个带符号的随机整数::r! hexdump -n $(((3 * 4))-e'“ \%d \ n”'/ dev / urandom
– HAL 9001
2015年2月16日在17:49
#2 楼
这是一个纯vimscript解决方案。我没有创建它,它是由Charles E. Campbell开发的。您可以在此处找到带有他的代码的Github存储库。该算法使用Vim启动时生成的3个种子,并根据应用于种子的计算和置换生成伪随机数:" 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
回购包含以下功能:
“随机” “种子的初始化;
从文本文件中读取用户定义的种子的方法;
伪随机生成器
多个随机函数:
在一定范围内生成随机数的函数
骰子滚动函数
随机交换一系列连续整数的函数
这是我编写的用于测试生成器的快速测试:我生成了0000000、9和c之间的1000000个数字忽略每个数字的出现次数,这里是结果:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
如您所见,世代似乎分布良好。我知道这在很大程度上不足以测试随机生成器,因此如果有空闲时间,我将尝试进行一些额外的分析。
#3 楼
这是一种在vim-randomtag插件中找到的方法,该方法基于以下信息:...当前时间微秒,仅在需要一些数字,对随机性质量不太关心或有安全方面的关注时可用。 br />function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
#4 楼
您可以使用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: https://stackoverflow.com/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]
#5 楼
Vim不提供本机随机生成器,但是,如果您使用Python编译了vim,则以下方法将在行尾添加一个随机数字::py import vim, random; vim.current.line += str(random.randint(0, 9))
注意:要检查您的vim是否支持Python,请尝试:
:echo has('python')
(如果是,则为1)。您还可以使用提供
$RANDOM
变量(与bash / ksh / zsh一起使用)的shell,该变量返回伪随机( 0-32767),例如::r! echo $RANDOM
或:
:put =system('echo $RANDOM')
或:
:r! od -An -td -N1 /dev/urandom
在Windows上,您必须安装Cygwin / MSYS / SUA,或者按照Carpetsmoker的建议使用
%RANDOM%
变量。如果您没有对于shell和Python的访问,作为解决方法,请使用当前时间戳的最后几位数字,例如:
:put =reltimestr(reltime())[-2:]
注意:如果您经常使用它,编写一个简单的函数
return reltimestr(reltime())[-4:]
。注意:以上方法仅返回一个伪随机整数,不应将其用于ge请对加密密钥进行加密。
要添加更多随机数,请按@:再次重复该命令。或以数字作为前缀(例如10 @ :),以添加更多由新行分隔的随机数。
相关:
VIM在stackoverflow的缓冲区中生成随机数
在stackoverflow的bash中生成随机数
评论
它也适用于zsh,但不适用于sh,破折号,鱼,csh或tcsh ...您可以使用:r! bash -c'echo $ RANDOM'...
–马丁·图尔诺伊(Martin Tournoij)
2015年2月15日在23:24
“从当前时间戳返回最后几位数字”->这不是随机的。即使是出于非加密目的,使用时间来获取伪随机数几乎总是一个坏主意。如果时间戳的分辨率以秒为单位,并且每秒创建两次“ file。$ random”,该怎么办?糟糕! ...另外,您永远都不知道何时有人要使用您的GetRandom()函数对prng有什么影响,因此,如果可能的话,最好从一开始就将其正确设置(并且几乎总是可以在这里实现!)
–马丁·图尔诺伊(Martin Tournoij)
2015年2月16日在10:06
我不知道$ RANDOM的质量如何,但是如果这不是一个较差的PRNG,那么这不是使用更差的PRNG的理由:-)相反,请升级到更好的PRNG!据我所知,/ dev / urandom在bash普遍可用的所有平台上都可用,因此我看不出不使用它的理由。
–马丁·图尔诺伊(Martin Tournoij)
2015年2月16日在10:59
我不知道$ RANDOM。似乎是一个非常不错的小工具,即使它可能是“穷人RNG”(如@Carpetsmoker指出的那样),也绝对符合@kenorb(提出问题的人)“容易记忆”的要求。
–Dalker
16-10-7在14:46
#6 楼
我认为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
请参阅我对通过python在vim中创建框的回答,以快速了解Vim中的Python脚本。
由于
vim.current.buffer
是字符串列表,因此我们可以像在Python中那样为它分配一个字符串列表。 random.sample
只是我想到的在Python中获取随机整数列表的最简单方法。评论
@Carpetsmoker random.sample在Python 2上仅提供两个参数,str是将内容转换为字符串的内置函数。让我查找Py3等效项(str相同,必须检查xrange和random.sample)。
–muru
2015年2月14日在23:47
@Carpetsmoker aargh,错字。 60之后的括号应该在10000之后。xrange在Python3中不存在,因为range是等效的(与Py2中的range不同,它们实际上都不构造列表)。
–muru
15年2月14日在23:55
@Carpetsmoker最后的区别是Py3中的map返回一个可迭代的列表而不是列表,因此最后一行将使用list(map(str,random.sample(range(10000),60)))
–muru
2015年2月14日在23:58
好的,我可以自由地通过一些(较小的)更改来编辑您的文章,以使其与Python 2和3兼容...
–马丁·图尔诺伊(Martin Tournoij)
2015年2月15日下午0:51
#7 楼
Vim v8.1.2342添加了rand
和srand
函数。我更喜欢这种方式在当前缓冲区中生成0-100范围内的20个随机数:
:put =rand()%100
20@:
评论
纯Vim吗?或者说,使用:python?纯vim是首选,但如果不是内置的,则任何易于记忆的方法都可以。