문제

현재 "A"에 대한 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에는 다음을 위한 메서드도 있습니다.

  • 베이스64
  • 무작위_바이트
  • 무작위_번호

보다: 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, "-" 및 "_"가 포함될 수 있습니다.패딩이 참인 경우에도 "="가 사용됩니다.

[*('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인 임의 문자열에 대한 한 줄의 간단한 코드입니다.

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

길이가 8인 임의의 비밀번호에도 사용할 수 있습니다.

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

나는 그것이 도움이 되고 놀라울 것이라고 믿습니다.

루비 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"

다음은 lenth 8의 임의 비밀번호에 대한 간단한 코드입니다.

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

내가 사용하고 싶은 또 다른 방법

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

Devise의 뭔가

나는 이것이 간결함, 명확성 및 수정 용이성의 균형이 잘 잡혀 있다고 생각합니다.

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 Ruby Gem의 측면에서 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. 보석 설치 위조자
  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은 엄청나지만 DB에 있는 1200개 정도의 코드 중 중복된 코드가 꽤 많았습니다.나는 그것들이 서로의 시간 경계에서 일어나는 것을 발견했습니다.즉, 12:12:23 및 2:12:22 또는 그와 유사한 듀플을 볼 수 있습니다. 시간이 문제인지 아닌지 확실하지 않습니다.

이 코드는 activerecord 객체를 생성하기 전에 있었습니다.레코드가 생성되기 전에 이 코드가 실행되어 '고유' 코드를 생성했습니다.db의 항목은 항상 안정적으로 생성되었지만 코드(위 줄의 str)가 너무 자주 복제되었습니다.

위의 줄을 약간의 지연으로 100,000번 반복하는 스크립트를 만들었으므로 매 시간마다 일종의 반복 패턴을 확인하는 데 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