私は現在、 "A" .. "Z"の8文字の擬似ランダムな大文字の文字列を生成しています。
value = ""; 8.times{value << (65 + Rand(25)).chr}
しかし、きれいには見えません。また、単一のステートメントではないため、引数として渡すことはできません。大文字と小文字が混在する文字列 "a" .. "z"と "A" .. "Z"を取得するために、次のように変更しました。
value = ""; 8.times{value << ((Rand(2)==1?65:97) + Rand(25)).chr}
しかし、それはゴミのように見えます。
誰より良い方法がありますか?
(0...8).map { (65 + Rand(26)).chr }.join
私はゴルフに時間がかかりすぎる。
(0...50).map { ('a'..'z').to_a[Rand(26)] }.join
そして最後のものは、さらに混乱を招きますが、より柔軟で、無駄なサイクルを減らします。
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
string = (0...50).map { o[Rand(o.length)] }.join
SecureRandomを使わないのはなぜですか?
require 'securerandom'
random_string = SecureRandom.hex
# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)
SecureRandomには以下のメソッドもあります。
参照してください: http://Ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html
保証された最大長を持つランダムなURLにやさしい文字列を生成するためにこれを使用します。
Rand(36**length).to_s(36)
小文字のa-zと0-9のランダムな文字列を生成します。あまりカスタマイズできませんが、短くてきれいです。
このソリューションは、アクティベーションコード用の読みやすい文字列を生成します。 8とB、1とI、0とO、Lと1などを混同したくありません。
# Generates a random string from a set of easily readable characters
def generate_activation_code(size = 6)
charset = %w{ 2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z}
(0...size).map{ charset.to_a[Rand(charset.size)] }.join
end
他の人が似たようなことを言っていますが、これはURLセーフ機能を使用しています。
require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
結果には、A〜Z、a〜z、0〜9、「 - 」、および「_」を含めることができます。パディングがtrueの場合、「=」も使用されます。
[*('A'..'Z')].sample(8).join
ランダムな8文字の文字列を生成します(例:NVAYXHGR)
([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(8).join
ランダムな8文字の文字列(3PH4SWF2など)を生成し、0/1/I/Oを除外します。 Ruby 1.9
Ruby 2.5以降はSecureRandom.alphanumeric
を使えばとても簡単です。
len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"
A〜Z、a〜z、0〜9を含むランダムな文字列を生成します。したがって、ほとんどの場合に適用できます。そして、それらはランダムに安全に生成されます。これも利益になるかもしれません。
編集:最も支持を得ているソリューションと比較するためのベンチマーク:
require 'benchmark'
require 'securerandom'
len = 10
n = 100_000
Benchmark.bm(12) do |x|
x.report('SecureRandom') { n.times { SecureRandom.alphanumeric(len) } }
x.report('Rand') do
o = [('a'..'z'), ('A'..'Z'), (0..9)].map(&:to_a).flatten
n.times { (0...len).map { o[Rand(o.length)] }.join }
end
end
user system total real
SecureRandom 0.429442 0.002746 0.432188 ( 0.432705)
Rand 0.306650 0.000716 0.307366 ( 0.307745)
したがって、Rand
解決策はSecureRandom
の約3/4の時間しかかかりません。本当にたくさんの文字列を生成するのであれば問題になるかもしれませんが、時々ランダムな文字列を作成するのであれば、もっと安全な実装を使うことをお勧めします。
私がこれを見つけた場所を思い出すことはできませんが、それは私にとって最も集中的で最もプロセスが少ないようです。
def random_string(length=10)
chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
password = ''
length.times { password << chars[Rand(chars.size)] }
password
end
require 'securerandom'
SecureRandom.urlsafe_base64(9)
指定した長さの文字列が必要な場合は、次のようにします。
require 'securerandom'
randomstring = SecureRandom.hex(n)
2n
と0-9
を含む長さa-f
のランダムな文字列を生成します
Array.new(n){[*"0".."9"].sample}.join
、ここではn = 8です。
一般化:Array.new(n){[*"A".."Z", *"0".."9"].sample}.join
など - from this answer
require 'sha1'
srand
seed = "--#{Rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]
これは長さ8のランダムな文字列の1行の単純なコードです。
random_string = ('0'..'z').to_a.shuffle.first(8).join
長さ8のランダムパスワードにも使えます
random_password = ('0'..'z').to_a.shuffle.first(8).join
私はそれが役立つと素晴らしいことを願っています。
Ruby 1.9以降:
ALPHABET = ('a'..'z').to_a
#=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
10.times.map { ALPHABET.sample }.join
#=> "stkbssowre"
# or
10.times.inject('') { |s| s + ALPHABET.sample }
#=> "fdgvacnxhc"
注意:Rand
は攻撃者にとって予測可能なので、おそらく安全ではありません。これがパスワードを生成するためのものである場合は、SecureRandomを確実に使用してください。私はこのようなものを使います:
length = 10
characters = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
password = SecureRandom.random_bytes(length).each_char.map do |char|
characters[(char.ord % characters.length)]
end.join
長さ8のランダムパスワードの簡単なコードを次に示します
Rand_password=('0'..'z').to_a.shuffle.first(8).join
それが役立つことを願っています。
私が使用したいもう一つの方法
Rand(2**256).to_s(36)[0..7]
あなたが本当に正しい文字列の長さに妄想しているならljustを追加してください:
Rand(2**256).to_s(36).ljust(8,'a')[0..7]
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
工夫から何か
ここにセントを追加するだけです。
def random_string(length = 8)
Rand(32**length).to_s(32)
end
ruby GemのFacets facets
のString#random
を使うことができます。
それは基本的にこれを行います:
class String
def self.random(len=32, character_set = ["A".."Z", "a".."z", "0".."9"])
characters = character_set.map { |i| i.to_a }.flatten
characters_len = characters.length
(0...len).map{ characters[Rand(characters_len)] }.join
end
end
私はこれが簡潔さ、明快さ、そして修正のしやすさの素晴らしいバランスであると思います。
characters = ('a'..'z').to_a + ('A'..'Z').to_a
# Prior to 1.9, use .choice, not .sample
(0..8).map{characters.sample}.join
たとえば、数字を含める:
characters = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
大文字の16進数
characters = ('A'..'F').to_a + (0..9).to_a
本当に印象的な文字の配列の場合:
characters = (32..126).to_a.pack('U*').chars.to_a
私のお気に入りは(:A..:Z).to_a.shuffle[0,8].join
です。シャッフルにはRuby> 1.9が必要です。
この解決策は外部からの依存を必要としますが、他のものよりもきれいです。
Faker::Lorem.characters(10) # => "ang9cbhoa8"
与えられた:
chars = [*('a'..'z'),*('0'..'9')].flatten
単一の式は、引数として渡すことができ、重複文字を許可します。
Array.new(len) { chars.sample }.join
私の2セント:
def token(length=16)
chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
(0..length).map {chars.sample}.join
end
私はちょうどほとんどの使用例のためにランダムなトークンを生成するために小さな宝石random_token
を書くだけで、楽しんでください〜
''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }
私は最近62文字から8バイトのランダムな文字列を生成するためにこのようなことをしていました。文字は0〜9、a〜z、A〜Zです。 8回ループし、配列からランダムな値を選択していたので、それらの配列を作成しました。これはRailsアプリの中です。
str = '' 8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[Rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }
奇妙なことに、私はたくさんの重複を得たということです。ランダムにこれが起こることはほとんどないはずです。 62 ^ 8は巨大ですが、データベース内の1200ほどのコードのうち、重複するコードが多数ありました。私はそれらがお互いの時間の境界で起こっているのに気づいた。言い換えれば、私は12時12分23秒と2時12分22秒に二重またはそのような何かを見るかもしれません...時間が問題であるかどうかわからない。
このコードは以前はactiverecordオブジェクトの作成中でした。レコードが作成される前は、このコードが実行されて「固有の」コードが生成されていました。データベース内のエントリは常に確実に生成されていましたが、コード(上の行のstr)が頻繁に複製されていました。
1時間ごとにある種の繰り返しパターンを見ることを期待して3〜4時間かかるように、私は少し遅れて上記の行の10万回の反復を実行するスクリプトを作成しましたが、何も見ませんでした。なぜこれが私のRailsアプリで起こったのか私にはわかりません。
あなたがUNIXを使っていて、まだRailsなしでRuby 1.8(SecureRandomではない)を使わなければならないなら、これを使うこともできます:
random_string = `openssl Rand -base64 24`
これは新しいシェルを生み出すことに注意してください。これは非常に遅く、スクリプトにのみ推奨されます。
Ruby 1.8以降で動作し、高速であるもう1つのトリックは以下のとおりです。
>> require "openssl"
>> OpenSSL::Random.random_bytes(20).unpack('H*').join
=> "2f3ff53dd712ba2303a573d9f9a8c1dbc1942d28"
ランダムな16進数文字列です。同様の方法でbase64文字列( 'M *')を生成できるはずです。
私はレーダーの答えが一番好きです、これまでのところ、私は思います。私はこのように少し微調整したいと思います:
CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def Rand_string(length=8)
s=''
length.times{ s << CHARS[Rand(CHARS.length)] }
s
end
この方法では、任意の長さを渡すことができます。デフォルトは6に設定されています。
def generate_random_string(length=6)
string = ""
chars = ("A".."Z").to_a
length.times do
string << chars[Rand(chars.length-1)]
end
string
end
私のベストショット、3つの範囲からなるランダムな文字列に対する2つの解決策
(('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a).sample(8).join
([*(48..57),*(65..90),*(97..122)]).sample(8).collect(&:chr)*""
これを試してみる
def Rand_name(len=9)
ary = [('0'..'9').to_a, ('a'..'z').to_a, ('A'..'Z').to_a]
name = ''
len.times do
name << ary.choice.choice
end
name
end
私は、スレッドの答えが大好きで、とても役に立ちました。本当に言っても、それらのどれもが私の目を満足させません。おそらくRand()メソッドでしょう。そのためにArray#選択メソッドがあるので、それは私には正しくないようです。
これは別の方法です:
require "securerandom"
が必要です
def secure_random_string(length = 32, non_ambiguous = false)
characters = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
%w{I O l 0 1}.each{ |ambiguous_character|
characters.delete ambiguous_character
} if non_ambiguous
(0...length).map{
characters[ActiveSupport::SecureRandom.random_number(characters.size)]
}.join
end
10.times do
alphabet = ('a'..'z').to_a
string += alpha[Rand(alpha.length)]
end
これは他のいくつかの答えに基づいていますが、もう少し複雑になります。
def random_password
specials = ((32..47).to_a + (58..64).to_a + (91..96).to_a + (123..126).to_a).pack('U*').chars.to_a
numbers = (0..9).to_a
alpha = ('a'..'z').to_a + ('A'..'Z').to_a
%w{i I l L 1 O o 0}.each{ |ambiguous_character|
alpha.delete ambiguous_character
}
characters = (alpha + specials + numbers)
password = Random.new.Rand(8..18).times.map{characters.sample}
password << specials.sample unless password.join =~ Regexp.new(Regexp.escape(specials.join))
password << numbers.sample unless password.join =~ Regexp.new(Regexp.escape(numbers.join))
password.shuffle.join
end
基本的には、長さが8 - 20文字で、少なくとも1つの数字と1つの特殊文字を含むパスワードを保証します。
Secure_validatableを考案するには、これを使用できます。
(0 ... 8).map {([65、97]。sample + Rand(26)).chr} .Push(Rand(99))。join
これが@Travis R回答の改良です。
def random_string(length=5)
chars = 'abdefghjkmnpqrstuvwxyzABDEFGHJKLMNPQRSTUVWXYZ'
numbers = '0123456789'
random_s = ''
(length/2).times { random_s << numbers[Rand(numbers.size)] }
(length - random_s.length).times { random_s << chars[Rand(chars.size)] }
random_s.split('').shuffle.join
end
@Travis Rの回答では文字と数字が一緒になっていたので、random_string
が数字だけまたは文字だけを返すことがありました。これにより、random_string
の少なくとも半分は文字になり、残りは数字になります。万が一、数字や文字を含むランダムな文字列が必要な場合
あなたの最初を1つのステートメントにするには:
(0...8).collect { |n| value << (65 + Rand(25)).chr }.join()
最も簡単な方法はstring_pattern gem https://github.com/MarioRuiz/string_pattern を使うことです。
例えば36個のランダムな文字を生成するには:
require 'string_pattern'
puts '36:L'.gen
正規表現も使えます
require 'string_pattern'
puts /[a-zA-Z]{36}/.gen
必要に応じて空の文字列またはプレフィックスを作成します。
myStr = "OID-"
このコードを使用して、文字列に乱数を入力します。
begin; n = ((Rand * 43) + 47).ceil; myStr << n.chr if !(58..64).include?(n); end while(myStr.length < 12)
ノート:
(Rand * 43) + 47).ceil
48-91(0,1,2..Y、Z)の乱数を生成します
!(58..64).include?(n)
特殊文字をスキップするために使用されます(私はそれらを含めることには興味がありません)
while(myStr.length < 12)
接頭辞を含めて合計12文字の長さの文字列が生成されます。
出力例:
"OID-XZ2J32XM"
a='';8.times{a<<[*'a'..'z'].sample};p a
または
8.times.collect{[*'a'..'z'].sample}.join
私たちのコードでこれを使ってきました:
class String
def self.random(length=10)
('a'..'z').sort_by {Rand}[0,length].join
end
end
サポートされている最大の長さは25です(私たちはとにかくデフォルトでそれを使用しています、従って問題ではありませんでした)。
不快な言葉の生成を完全に避けたいのであれば、 'a' .. 'z'は最適ではないと誰かが言っています。私たちが持っていたアイデアの1つは母音を削除することでした、しかしあなたはまだWTFBBQなどで終わります。
`pwgen 8 1`.chomp
これは柔軟性があり、重複を許すソリューションです:
class String
# generate a random string of length n using current string as the source of characters
def random(n)
return "" if n <= 0
(chars * (n / length + 1)).shuffle[0..n-1].join
end
end
例:
"ATCG".random(8) => "CGTGAAGA"
特定の文字をより頻繁に出現させることもできます。
"AAAAATCG".random(10) => "CTGAAAAAGC"
説明:上記の方法は、指定されたストリングの文字を取り、十分に大きい配列を生成します。それはそれをそれから切り直し、最初のn個のアイテムを取り、そしてそれらを結合する。
Array.new(8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 57
(1..8).inject(""){|r|r<<('0'..'z').to_a.shuffle[0]} # 51
e="";8.times{e<<('0'..'z').to_a.shuffle[0]};e # 45
(1..8).map{('0'..'z').to_a.shuffle[0]}.join # 43
(1..8).map{Rand(49..122).chr}.join # 34
'SafeRandom' Gem GithubLink を使用してください
これは、Rails 2、Rails 3、Rails 4、Rails 5互換の乱数値を生成する最も簡単な方法を提供します。