質問

現在、「A」に対して 8 文字の擬似ランダムな大文字文字列を生成しています。「Z」:

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 には次のメソッドもあります。

  • Base64
  • ランダムバイト
  • 乱数

見る: 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 を除きます。ルビー 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 ソリューションにかかる時間はわずか 3/4 SecureRandom. 。本当に大量の文字列を生成する場合には問題になるかもしれませんが、時々ランダムな文字列を作成するだけの場合は、常により安全な実装を使用します (呼び出しが簡単でより明示的であるため)。

これをどこで見つけたのか思い出せませんが、私にとってはこれが最良かつ最もプロセス集約度が低いように思えます。

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, 、など。- から これ 答え

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"

これは、長さが 8 のランダムなパスワードの 1 つの簡単なコードです。

rand_password=('0'..'z').to_a.shuffle.first(8).join

それが役立つことを願っています。

注意してください: 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

私が好んで使用するもう 1 つの方法

 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')

デバイスからの何か

これは、簡潔さ、明確さ、変更の容易さのバランスが取れていると思います。

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

ここに私のセントを追加するだけです...

def random_string(length = 8)
  rand(32**length).to_s(32)
end

使用できます String#random ルビー宝石のファセットから facets:

https://github.com/rubyworks/facets/blob/126a619fd766bc45588cac18d09c4f1927538e33/lib/core/facets/string/random.rb

基本的にこれを行います:

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

私のお気に入りは (:A..:Z).to_a.shuffle[0,8].join. 。シャッフルには Ruby 1.9 以上が必要であることに注意してください。

このソリューションは外部依存性を必要としますが、他のソリューションよりも優れているようです。

  1. gemをインストールする 偽者
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"

与えられる:

chars = [*('a'..'z'),*('0'..'9')].flatten

単一の式。引数として渡すことができ、重複文字を許可します。

Array.new(len) { chars.sample }.join

最近、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) が頻繁に複製されていました。

上記の行をわずかな遅延で 100,000 回繰り返し実行するスクリプトを作成したため、1 時間ごとに何らかの繰り返しパターンが表示されることを期待して 3 ~ 4 時間かかりますが、何も表示されませんでした。私の Rails アプリでなぜこれが起こったのかわかりません。

''.tap {|v| 4.times { v << ('a'..'z').to_a.sample} }

私の2セント:

  def token(length=16)
    chars = [*('A'..'Z'), *('a'..'z'), *(0..9)]
    (0..length).map {chars.sample}.join
  end

私はただ小さな宝石を書くだけです random_token ほとんどのユースケースでランダムなトークンを生成するには、~ をお楽しみください

https://github.com/sibevin/random_token

このメソッドを使用すると、任意の長さを渡すことができます。デフォルトでは 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

これまでのところ、Radar の答えが一番好きだと思います。私なら次のように少し調整します。

CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
  s=''
  length.times{ s << CHARS[rand(CHARS.length)] }
  s
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top