سؤال

أنا حاليا توليد 8-الشخصية شبه عشوائي الكبيرة سلسلة "A" .."Z":

value = ""; 8.times{value  << (65 + rand(25)).chr}

ولكنها لا تبدو نظيفة, و لا يمكن أن تكون مرت حجة لأنه ليس بيان واحد.للحصول على حالة مختلط سلسلة "a" .."z" بالإضافة إلى "هناك" .."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
  • random_bytes
  • random_number

انظر: 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 مع ب ، 1 ، 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

منذ روبي 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"

هنا هو واحد بسيط رمز مرور عشوائية مع ينث 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]

إضافة فقط إذا كنت حقا بجنون العظمة حول تصحيح طول السلسلة:

 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

الأحرف الكبيرة الست عشري:

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.علما بأن خلط يتطلب روبي > 1.9.

هذا الحل يحتاج تبعية خارجية ، ولكن يبدو أجمل من الآخر.

  1. تثبيت الأحجار الكريمة فاكر
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"

بالنظر إلى:

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

تعبير واحد ، يمكن أن تنتقل كحجة ، يسمح أحرف مكررة:

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

كنت تفعل شيئا من هذا القبيل في الآونة الأخيرة إلى توليد 8 بايت سلسلة عشوائية من 62 الشخصيات.وكانت شخصيات 0-9,a-z,a-Z.لدي مجموعة منهم كما كان التكرار 8 مرات و اختيار عشوائي قيمة من المصفوفة.هذا كان داخل القضبان التطبيق.

str = '' 8.times {|i| str << ARRAY_OF_POSSIBLE_VALUES[rand(SIZE_OF_ARRAY_OF_POSSIBLE_VALUES)] }

الشيء الغريب هو أنني حصلت على عدد لا بأس به من التكرارات.الآن عشوائيا هذا تقريبا لم يحدث.62^8 ضخمة ، ولكن من 1200 أو حتى رموز في db كان عدد كبير من التكرارات.لاحظت منهم يحدث على ساعة حدود بعضها البعض.وبعبارة أخرى أنا قد نرى ثنائي في 12:12:23 2:12:22 أو شيء من هذا القبيل...لست متأكدا إذا كان الوقت هو المشكلة أم لا.

هذا الرمز كان قبل خلق من activerecord الكائن.قبل أن المحضر تم إنشاء هذه المدونة تشغيل وتوليد 'فريدة من نوعها' رمز.الإدخالات في db كانت تنتج دائما بشكل موثوق ، ولكن قانون (شارع في السطر أعلاه) كانت تتكرر كثيرا في كثير من الأحيان.

أنا خلقت النصي لتشغيله من خلال 100000 التكرار من هذا السطر أعلاه مع تأخير صغير لذلك سوف يستغرق 3-4 ساعات على أمل أن نرى نوعا من تكرار نمط على أساس كل ساعة, ولكن رأيت شيئا.ليس لدي فكرة لماذا كان هذا يحدث في بلدي القضبان التطبيق.

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

مع هذا الأسلوب يمكنك تمرير في abitrary طول.هو تعيين افتراضي 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

أنا مثل الرادار الجواب الأفضل حتى الآن على ما أعتقد.أود قرص قليلا مثل هذا:

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