回答:
このための組み込み機能はないため、外部の何かを使用する必要があります。
/bin/sh
)呼び出し:
strings -n 1 < /dev/urandom | tr -d '[:space:]' | head -c15
with 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スクリプトはPythonスクリプトよりも一般的であるように思われるため、Rubyがおそらく次に最適な選択肢です。乱数の取得は簡単です:
: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ソリューションです。私は作成しませんでした。CharlesE. 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
リポジトリには次の機能が含まれます。
ジェネレーターをテストするために作成した簡単なテストを次に示します。0〜9の1000000個の数値を生成し、各数値の出現回数をカウントしました。結果は次のとおりです。
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
例のように、疑似乱数(0-32767)を返す変数(bash / ksh / zshで動作)を提供するシェルを使用することもできます。
: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()
良いprng が重要な場合に誰かがあなたの関数をいつ使用するかわからないので、可能であれば最初から正しくすることをお勧めします(そして、ほとんど常にここで可能です!)
$RANDOM
が、これが悪いPRNGである場合、それはさらに悪いPRNGを使用する理由ではない:-)代わりに、より良いPRNGにアップグレードしてください!私の知る限り、一般的に利用可能な/dev/urandom
すべてのプラットフォームでbash
利用できるため、使用しない理由はわかりません。
$RANDOM
。@Carpetsmokerが指摘しているように、「貧乏人のRNG」かもしれませんが、それは@kenorb(質問をした人)の「簡単に覚えやすい」という要件に間違いなく適合しています。
Vimバイナリにパッチ8.1.2342が含まれている場合、関数rand()
とsrand()
関数を使用できます。
例として、改行で区切られた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の2つの引数のみを返しstr
ます。これは、文字列に変換する組み込み関数です。Py3の同等物を調べてみましょう(str
同じで、確認する必要がxrange
ありますrandom.sample
)
xrange
、Python3にはありません。これrange
は同等であるためです(range
Py2 とは異なり、実際にはリストを構築しません)。
map
、Py3でリストではなく反復可能を返すため、最後の行が使用されることですlist(map(str, random.sample(range(10000), 60)))
:python
?を使用して?