Answers:
没有内置的功能,因此您需要使用外部的东西。
/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解决方案。我没有创建它,它是由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
回购包含以下功能:
这是我编写的用于测试生成器的快速测试:我生成了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不提供本机随机生成器,但是,如果您使用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,或%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")
要生成小于100的10个随机数:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
要生成5个字符的10个随机字母字符串:
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")
要生成5个随机词的10个序列:
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
?