Respostas:
Não há um recurso interno para isso, então você precisará usar algo externo.
/bin/sh)A ligar:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
com system()é um bom caminho. Você pode obter apenas números substituindo trpor grep:
strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15
Você pode usar isso no Vim assim:
:echo system("strings -n 1 < /dev/urandom | grep -o '[[:digit:]]' | head -c15")
O número 15 é a quantidade de números que você deseja (ajuste de acordo). Isso deve funcionar no Linux, BSD, OSX e outros sistemas UNIX. Não vai funcionar no MS Windows.
Veja também o meu blog " Gerar senhas a partir da linha de comando " (existem muitas soluções ruins para isso).
Ruby é provavelmente a próxima melhor opção, pois os scripts Ruby parecem ser um pouco mais comuns que os scripts Python. Obter um número aleatório é fácil:
:ruby puts Random.rand(10)
Ou para obter 15 números:
:ruby 15.times { puts Random.rand(10) }
Você pode usar o módulo aleatório ; para obter um único número:
:py import random; print(random.randint(0, 9))
Ou 15 números:
:py import random
:py for i in range(0, 15): print(random.randint(0, 9))
Isso deve funcionar para o Python 2 e 3.
Você pode usar Get-Random
para obter um número aleatório:
:echo system('Get-Random')
cmd.exeO Windows 7 e posterior devem ser fornecidos com o PowerShell, mas se você quiser compatibilidade máxima, poderá usá-lo cmd.exe. Tem uma variável especial %RANDOM%:
:echo system('@echo %RANDOM%')
Nota: Isso não é muito aleatório! , usa o tempo (!)
Observe que você não precisa usar as ligações Ruby ou Python para usar as soluções Ruby ou Python; você também pode criar um script separado e chamá-lo com
system("python -c '...'")(isso requer que o ruby / python esteja instalado, obviamente.
tr -d '[:space:]', talvez tr -cd '[:digit:]'para o filtro grep?
:r! hexdump -n $((3*4)) -e '"%d"' /dev/urandom, geraria 3 números inteiros assinados aleatoriamente.
:r! hexdump -n $((3*4)) -e '"\%d\n"' /dev/urandom
Aqui está uma solução pura para vimscript . Eu não o criei, ele foi desenvolvido por Charles E. Campbell. Você pode encontrar um repositório do Github com seu código aqui .
O algoritmo usa 3 sementes geradas na inicialização do Vim e gera um número pseudo-aleatório com base nos cálculos e permutações aplicados às sementes:
" 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
O escopo das variáveis é declarado como global porque é usado pela função do gerador, mas pode ser restrito ao script ( s:)
E aqui está a função do gerador:
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
O repo inclui as seguintes funções:
Aqui está um teste rápido que escrevi para testar o gerador: gerei 1000000 números entre 0 e 9 e contei o número de ocorrências de cada número. Aqui estão os resultados:
0 : 100409
1 : 99435
2 : 100433
3 : 99578
4 : 100484
5 : 99948
6 : 100394
7 : 99649
8 : 99803
9 : 99867
Como você pode ver, a geração parece estar bem distribuída. Estou ciente de que isso não é suficiente para testar um gerador aleatório, então tentarei fazer uma análise extra se tiver algum tempo livre.
Este é um método encontrado no plug - in vim-randomtag , baseado na leitura ... microssegundos para o horário atual, utilizável quando você deseja apenas um número, não se importa muito com a qualidade da aleatoriedade ou se preocupa com a segurança, etc .:
function! s:randnum(max) abort
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:]) % a:max
endfunction
O Vim não oferece gerador aleatório nativo; no entanto, se você tiver o vim compilado com Python, o método a seguir anexará um dígito aleatório no final da sua linha:
:py import vim, random; vim.current.line += str(random.randint(0, 9))
Nota: Para verificar se o seu vim suporta Python, tente: :echo has('python')(1 para sim).
Você também pode usar o shell que oferece $RANDOMvariável (funciona com bash / ksh / zsh) que retorna um pseudo-aleatório (0-32767), por exemplo:
:r! echo $RANDOM
ou:
:put =system('echo $RANDOM')
ou:
:r! od -An -td -N1 /dev/urandom
No Windows, você deve ter o Cygwin / MSYS / SUA instalado ou usar a %RANDOM%variável conforme sugerido por Carpetsmoker .
Se você não tem acesso ao shell e ao Python, como solução alternativa, use os últimos dígitos do carimbo de data / hora atual, por exemplo:
:put =reltimestr(reltime())[-2:]
Nota: Se você o estiver usando com bastante frequência, escreva uma função simples que sim return reltimestr(reltime())[-4:].
Nota: Os métodos acima retornam apenas um número inteiro pseudoaleatório que não deve ser usado para gerar uma chave de criptografia.
Para adicionar mais números aleatórios, pressione @:para repetir o comando novamente. Ou prefixe com number (like 10@:) para adicionar muito mais números aleatórios separados por novas linhas.
Palavras-chave:
zsh, mas não com sh, dash, fish, csh, ou tcsh... Você pode usar :r! bash -c 'echo $RANDOM'...
GetRandom()função onde a boa impressão é importante, por isso é melhor acertar desde o início, se possível (e quase sempre é possível aqui!)
$RANDOM, mas se esse é um PRNG ruim, não é uma razão para usar um PRNG ainda mais pobre :-) Em vez disso, atualize para um PRNG melhor! Tanto quanto eu sei, /dev/urandomestá disponível em todas as plataformas onde bashestá comumente disponível, então não vejo um motivo para não usá-lo.
$RANDOM. Parece uma pequena ferramenta muito boa, e mesmo que seja um "RNG do pobre" (como aponta a @Carpetsmoker), definitivamente se encaixa no requisito de "facilmente memorável" do @ kenorb (que fez a pergunta).
Você pode usar as funções rand()e srand(), desde que o seu binário Vim inclua o patch 8.1.2342 .
Como exemplo, para gerar 10 números aleatórios separados por novas linhas:
let seed = srand()
echo range(10)->map({-> rand(g:seed)})->join("\n")
Para gerar 10 números aleatórios, todos inferiores a 100:
let seed = srand()
echo range(10)->map({-> rand(g:seed) % 100})->join("\n")
Para gerar 10 seqüências alfabéticas aleatórias de 5 caracteres:
let seed = srand()
echo range(10)
\ ->map({-> range(5)
\ ->map({-> (97+rand(g:seed) % 26)->nr2char()})->join('')})
\ ->join("\n")
Para gerar 10 palavras aleatórias (extraídas do arquivo do dicionário /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")
Para gerar 10 sequências de 5 palavras aleatórias:
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")
Para gerar uma versão UUID aleatória 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], '')
Para aplicar um esquema de cores aleatório:
let seed = srand()
let colorschemes = getcompletion('', 'color')
let len = colorschemes->len()
exe 'colo '..colorschemes[rand(seed) % len]
Eu não acho que exista uma função nativa para números aleatórios no Vimscript.
Uma maneira de usar :python(use-o em uma função, talvez, com 10000 e 60 substituídos por parâmetros):
: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
Veja minha resposta para Criando uma caixa no vim via python para uma rápida introdução sobre scripts em Python no Vim.
Como vim.current.bufferé uma lista de cadeias de caracteres, podemos atribuir uma lista de cadeias de caracteres da mesma maneira que atribuiríamos no Python. random.sampleé apenas a maneira mais simples de obter uma lista de números inteiros aleatórios em Python.
random.sampleexige apenas dois argumentos no Python 2, stré a função interna de converter coisas em strings. Deixe-me procurar os equivalentes Py3 ( strseria o mesmo, terá que verificar xrangee random.sample).
xrangenão está no Python3 porque rangeé equivalente (nem na verdade constrói uma lista, ao contrário rangedo Py2).
mapem PY3 retorna um iterável e não uma lista, para a última linha usarialist(map(str, random.sample(range(10000), 60)))
:python?