रूबी में एक यादृच्छिक स्ट्रिंग कैसे उत्पन्न करें


746

मैं वर्तमान में "A" .. "Z" के लिए 8-वर्ण का छद्म-यादृच्छिक अपरकेस स्ट्रिंग उत्पन्न कर रहा हूं।

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

लेकिन यह साफ नहीं दिखता है, और इसे एक तर्क के रूप में पारित नहीं किया जा सकता है क्योंकि यह एक बयान नहीं है। मिश्रित-केस स्ट्रिंग "ए" .. "जेड" प्लस "ए" .. "जेड" प्राप्त करने के लिए, मैंने इसे बदल दिया:

value = ""; 8.times{value << ((rand(2)==1?65:97) + rand(25)).chr}

लेकिन यह कचरा जैसा दिखता है।

क्या किसी के पास बेहतर तरीका है?


मुझे समझ में नहीं आता कि आप क्यों परवाह करते हैं कि "चूंकि यह एक भी बयान नहीं है, इसे एक तर्क के रूप में पारित नहीं किया जा सकता है"। क्यों न इसे केवल एक उपयोगिता या सहायक विधि बनाया जाए?
डेविड जे।

1
मान लीजिए कि उपयोगकर्ता के पासवर्ड को रीसेट करने की एक विधि है और इसमें नए पासवर्ड के लिए एक तर्क है। मैं एक यादृच्छिक स्ट्रिंग में पास करना चाहता हूं, उपरोक्त कोड में मुझे एक tmp वैरिएबल की आवश्यकता है, जबकि एकल स्टेटमेंट उदाहरणों में मैं पूरी तरह से एक लाइनर के रूप में कर सकता हूं। यकीन है कि एक उपयोगिता विधि लंबे समय में अच्छी हो सकती है, अगर मुझे यहां और वहां समान होने की आवश्यकता है, लेकिन कभी-कभी आप इसे जगह में चाहते हैं, एक बार, किया।
जेफ

नहीं, आपको एक अस्थायी चर का उपयोग करने की आवश्यकता नहीं है। इसे आज़माएँ: reset_user_password!(random_string)जहाँdef random_string; SecureRandom.urlsafe_base64(20) end
डेविड जे।

8 अक्षर एक शर्मनाक कमजोर पासवर्ड है। Md5sum को देखते हुए एक आधुनिक पीसी 30 सेकंड में पासवर्ड पुनर्प्राप्त कर सकता है । कैसे कुछ लंबे समय के बारे मेंsecurerandom.urlsafe_base64
कर्नल आतंक

1
इसके इतने उत्तर क्यों हैं? ऐसा नहीं है कि यह एक उपयोगी प्रश्न नहीं है, लेकिन मैं उत्सुक हूं कि इसने कैसे ध्यान आकर्षित किया है।
लो

जवाबों:


969
(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

204
34 अक्षर और धधकते तेज ('a'..'z').to_a.shuffle[0,8].join:। ध्यान दें आपको रूबी> = 1.9 की आवश्यकता होगी shuffle
fny

20
मौजूदा पुस्तकालयों का लाभ उठाना बेहतर है जब तक कि आपके पास अपना रोल करने के लिए ड्राइवर न हो। SecureRandomएक उदाहरण के रूप में देखें , अन्य उत्तरों में।
डेविड जे।

28
@faraz आपकी विधि कार्यात्मक रूप से समान नहीं है, यह प्रतिस्थापन के साथ यादृच्छिक नहीं है।
मिचेल्टोफिश

35
[*('a'..'z'),*('0'..'9')].shuffle[0,8].joinपत्र और संख्या दोनों के साथ एक यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए।
रोबिन

31
randनियतात्मक और पूर्वानुमेय है। पासवर्ड बनाने के लिए इसका उपयोग न करें! SecureRandomइसके बजाय समाधान में से एक का उपयोग करें ।
पेंसिल

800

सिक्योर रैंडम का उपयोग क्यों नहीं करते?

require 'securerandom'
random_string = SecureRandom.hex

# outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)

SecureRandom के लिए भी तरीके हैं:

  • बेस 64
  • random_bytes
  • यादृच्छिक संख्या

देखें: http://ruby-doc.org/stdlib-1.9.2/libdoc/securerandom/rdoc/SecureRandom.html


11
base64 होगा, लेकिन अपने उदाहरण में हेक्स की तरह नहीं
जेफ डिके

67
वैसे, यह 1.9 और हाल के 1.8 संस्करणों में stdlib का हिस्सा है, इसलिए कोई भी require 'securerandom'इस स्वच्छ SecureRandomसहायक पाने के लिए हो सकता है :)
J -_- L

21
BTW SecureRandom को 3.2 वर्जन में ActiveSupport से हटा दिया गया था। चैंजोग से: "हटाए गए एक्टिवसुपोर्ट :: सिक्योररजैंडम के पक्ष में सिक्योर रैंडम लाइब्रेरी से।"
मार्क

15
SecureRandom.random_number(36**12).to_s(36).rjust(12, "0")0-9a-z (36 वर्ण) के साथ एक स्ट्रिंग उत्पन्न करेगा जो कि हमेशा 12 वर्णों का होता है। आप जो भी लंबाई चाहते हैं, उसे 12 बदलें। दुर्भाग्य से कोई रास्ता नहीं है सिर्फ AZ का उपयोग कर पाने के लिए Integer#to_s
गेरी शॉ

1
@ stringo0 जो गलत है। यदि आप +fGH1एक URL से गुजरना चाहते हैं , तो आपको बस URL को एनकोड करना होगा, जैसे कि आप किसी भी मूल्य को URL से गुजर रहे हैं: %2BfGH1
nzifnab

247

मैं गारंटीकृत अधिकतम लंबाई के साथ यादृच्छिक URL फ्रेंडली स्ट्रिंग्स उत्पन्न करने के लिए इसका उपयोग करता हूं:

rand(36**length).to_s(36)

यह लोअरकेस एज़ और 0-9 के यादृच्छिक तार उत्पन्न करता है। यह बहुत अनुकूलन योग्य नहीं है, लेकिन यह छोटा और साफ है।


4
सबसे छोटे संस्करण के लिए +1 (जो बाहरी बायनेरिज़ को कॉल नहीं करता ^ ^)। यदि यादृच्छिक स्ट्रिंग सार्वजनिक रूप से सामना नहीं कर रही है, तो मैं कभी-कभी केवल उपयोग भी करता हूं rand.to_s; बदसूरत, लेकिन काम करता है।
जो लिस

12
यह एक महान समाधान है (और तेज़, भी), लेकिन यह कभी-कभी लंबाई के तहत एक स्ट्रिंग पैदा करेगा length, लगभग ~ 40 में एक बार
ब्रायन ई

7
@Brian E यह उन अंकों की गारंटी देगा जो आप चाहते हैं (36**(length-1) + rand(36**length)).to_s(36):। 36 ** (लंबाई -1) को आधार 36 में परिवर्तित किया गया है 10 ** (लंबाई -1), जो सबसे छोटी मान है जिसे अंकों की लंबाई चाहिए।
एरिक हू

11
यहाँ हमेशा वांछित लंबाई के टोकन का उत्पादन करने वाला संस्करण है:(36**(length-1) + rand(36**length - 36**(length-1))).to_s(36)
एड्रियन जेरथॉन

3
यह मेरे लिए रेल्स 4 और रूबी 2.1.1: NameError: undefined local variable or method लंबाई 'में मुख्य के लिए एक त्रुटि करता है : ऑब्जेक्ट`
काकुबई

175

यह समाधान सक्रियण कोड के लिए आसानी से पढ़ने योग्य वर्णों की एक स्ट्रिंग उत्पन्न करता है; मैं नहीं चाहता था कि लोग 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

3
क्या 'U' अस्पष्ट है या वह टाइपो है?
gtd

10
@gtd - हां। U और V अस्पष्ट हैं।
कॉलिनम

1
@colinm V की हालांकि वहाँ है।
gtd

8
सुरक्षित होने की आप भी उपयोग करना चाहते हैं SecureRandom.random_number(charset.size)के बजायrand(charset.size)
gtd

1
मैं सिर्फ इस पर सुधार करने की कोशिश कर रहा था, निचले मामले और / या कुछ विशेष वर्णों (शिफ्ट + संख्या) को जोड़कर, और निम्न सूचियां मिलीं: %w{ A C D E F G H J K L M N P Q R T W X Y Z 2 3 4 6 7 9 ! @ # $ % ^ & * +}और %w{ A D E F G H J L N Q R T Y a d e f h n r y 2 3 4 7 ! @ # $ % ^ & * }(पहली सूची में निचला मामला शामिल नहीं है, लेकिन यह लंबा है) किंडा दिलचस्प है कि कैसे हल निकाला।
डेक्निफिन

130

दूसरों ने कुछ इसी तरह का उल्लेख किया है, लेकिन यह URL सुरक्षित फ़ंक्शन का उपयोग करता है।

require 'securerandom'
p SecureRandom.urlsafe_base64(5) #=> "UtM7aa8"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="

परिणाम में AZ, az, 0-9, "-" और "_" शामिल हो सकते हैं। यदि पैडिंग सही है तो "=" का भी उपयोग किया जाता है।


यही वह है जिसकी तलाश में मैं हूं। धन्यवाद!
डैन विलियम्स

69

रूबी 2.5 के बाद से, यह वास्तव में आसान है SecureRandom.alphanumeric:

len = 8
SecureRandom.alphanumeric(len)
=> "larHSsgL"

यह AZ, az और 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। यदि आप बहुत सारे तार उत्पन्न करते हैं, तो यह महत्वपूर्ण हो सकता है, लेकिन यदि आप समय-समय पर कुछ यादृच्छिक स्ट्रिंग बनाते हैं, तो मैं हमेशा अधिक सुरक्षित कार्यान्वयन के साथ जाऊंगा क्योंकि यह कॉल करने में आसान और अधिक स्पष्ट है।


48
[*('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


4
केवल समस्या ही परिणाम में प्रत्येक वर्ण अद्वितीय है। संभव मूल्यों को सीमित करता है।
tybro0103

1
यदि यह सुविधा अनुरोध गुजरता है, तो रूबी 1.9.x प्रतिकृति के बिना नमूने के लिए # नमूना के साथ समाप्त हो सकता है और प्रतिस्थापन के साथ नमूने के लिए #choice हो सकता है।
डेविड जे।

यह एक त्रुटि है, मुझे लगता है कि आपको आवश्यकता है ... [*("A".."Z")]'; ((एकल qoutes नहीं))
jayunit100

क्या आप मुझे बता मैं कैसे कर सकते हैं कर सकते हैं stubके लिए इस rspecपारित करने के लिए।
सिन्स्करी जूल

31

मुझे याद नहीं है कि मुझे यह कहाँ मिला है, लेकिन यह मेरे लिए सबसे अच्छा और कम से कम प्रक्रिया गहन जैसा लगता है:

def random_string(length=10)
  chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
  password = ''
  length.times { password << chars[rand(chars.size)] }
  password
end

7
शायद आप इसे यहाँ पाया? travisonrails.com/2007/06/07/generate-random-text-with-ruby
घातक

क्या इसमें से 0 और 1 गायब नहीं है?
सूर्यनिरजेंजा

ऐसा लगता है कि जहां मुझे यह मिल सकता है।
ट्रैविस रीडर

और फिर, ऐसा लगता है कि 0 और 1 गायब हैं।
ट्रैविस रीडर

4
0और 1और Oऔर Iजानबूझकर अनदेखा कर रहे थे क्योंकि उन अक्षरों को अस्पष्ट हैं। यदि इस प्रकार के कोड का उपयोग उन वर्णों के समूह को उत्पन्न करने के लिए किया जा रहा है, जिन्हें उपयोगकर्ता को कॉपी करने की आवश्यकता है, तो उन वर्णों को बाहर करना सबसे अच्छा है, जो संदर्भ से अलग करना मुश्किल हो सकता है।
एंड्रयू

28
require 'securerandom'
SecureRandom.urlsafe_base64(9)

सिक्योर रैंडम एक उत्कृष्ट लीब है। मुझे नहीं पता था कि यह वहाँ था। धन्यवाद।
डॉगवॉटर

पुरानी Random.new.bytes(9)
खोपड़ी

4
btw, urlsafe_base64 एक स्ट्रिंग को इंगित की गई 4/3 लंबाई देता है। एक स्ट्रिंग प्राप्त करने के लिए बिल्कुल एन चार लंबे, प्रयास करेंn=9 ; SecureRandom.urlsafe_base64(n)[0..n-1]
टार्डेट करें

25

यदि आप निर्दिष्ट लंबाई की एक स्ट्रिंग चाहते हैं, तो उपयोग करें:

require 'securerandom'
randomstring = SecureRandom.hex(n)

यह लंबाई 2nयुक्त एक यादृच्छिक स्ट्रिंग उत्पन्न करेगा 0-9औरa-f


यह लंबाई की एक स्ट्रिंग उत्पन्न नहीं करता है n, यह वास्तव में एक स्ट्रिंग उत्पन्न करता है जो 4/3 है n
उमर अली

@OmarAli तुम गलत हो। रूबी प्रलेखन के अनुसार .hexयह 2n के मामले में है। प्रलेखन: SecureRandom.hex एक यादृच्छिक हेक्साडेसिमल स्ट्रिंग उत्पन्न करता है। तर्क n लंबाई निर्दिष्ट करता है, बाइट्स में, उत्पन्न होने वाली यादृच्छिक संख्या की। परिणामस्वरूप हेक्साडेसिमल स्ट्रिंग की लंबाई एन से दोगुनी है ।
रिहर्सल


11
require 'sha1'
srand
seed = "--#{rand(10000)}--#{Time.now}--"
Digest::SHA1.hexdigest(seed)[0,8]

दिलचस्प है, लेकिन काफी अधिक कम्प्यूटेशनल रूप से महंगा
जेफ़

इसके अलावा पात्रों के सीमित दायरे के लिए कोई क्षमता नहीं है।
केंट फ्रेड्रिक

3
ध्यान रखें कि एक हेक्स डाइजेस्ट केवल 0-9 और एफआर वर्णों को वापस करता है।
वेबम

11

यहां लंबाई 8 के साथ यादृच्छिक स्ट्रिंग के लिए एक पंक्ति सरल कोड है:

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

आप इसका उपयोग यादृच्छिक पासवर्ड की लंबाई 8 के लिए भी कर सकते हैं:

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

2
अपने आप को पासवर्ड बनाने के लिए आपको इसका उपयोग नहीं करना चाहिए, क्योंकि यह विधि कभी भी चरित्र को नहीं दोहराएगी। इसलिए आप केवल P(36, 8) / 36^8 = 0.48 वर्णों के लिए संभावित वर्ण स्थान का उपयोग कर रहे हैं (~ बल को 2x आसान) या P(36, 25) / 36^25 = 0.0000125 वर्णों के लिए संभावित वर्ण स्थान (~ बल बल के लिए ~ 100,000x आसान)।
ग्लेशियल्स

10

रूबी 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"

1
mapसमाधान वास्तव में अच्छा है!
मीशा मोरशको

आप पूछ सकते हैं #sampleकि आपको कितने तत्व चाहिए। जैसे ALPHABET.sample(10).join... ruby-doc.org/core-2.4.0/Array.html#method-i-ample
odlp

यह वास्तव में गलत है। sample(10)आप 10 अद्वितीय नमूने देता है। लेकिन आप उन्हें दोहराना चाहते हैं। लेकिन मैं Array.new(10).mapप्रदर्शन के लिए उपयोग करूंगा
Saaaa Zejnilović

मुझे निचले और ऊपरी दोनों मामलों में अल्फ़ान्यूमेरिक चाहिए था। मैंने भी उपयोग करने के लिए स्विच किया है Array.newऔर इसके ब्लॉक सिंटैक्स। Array.new(20) { [*'0'..'9', *'a'..'z', *'A'..'Z'].sample }.join
taylorthurlow

8

जागरूक रहें: 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

यह संभवतः "सबसे" सुरक्षित समाधान है। सिक्योर रैंडम ऑपरेटिंग सिस्टम द्वारा प्रदान किए गए अंतर्निहित सुरक्षा एपीआई का उपयोग करने का प्रयास करता है। यदि आपके पास OpenSSL है तो वह इसका उपयोग करेगा, यदि आप विंडोज पर हैं तो यह वहां सबसे अच्छा विकल्प होगा। मुझे यह समाधान विशेष रूप से पसंद है क्योंकि यह आपको उपयोग के लिए वर्णों का एक सेट निर्दिष्ट करने की अनुमति देता है। हालांकि यह काम नहीं करेगा यदि आपका चरित्र सेट बाइट के अधिकतम मूल्य से अधिक है: 255। मैं डॉक्टर में SecureRandom के लिए स्रोत कोड देखने की सलाह देता हूं: ruby-doc.org/stdlib-1.9.3/libdoc/cecurerandom/ rdoc /…
ब्रीडली

8

यहां लंबाई 8 के साथ यादृच्छिक पासवर्ड के लिए एक सरल कोड है:

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

7

एक अन्य विधि जिसका मैं उपयोग करना चाहता हूं:

 rand(2**256).to_s(36)[0..7]

जोड़ें ljustयदि आप वास्तव में सही स्ट्रिंग लंबाई के बारे में पागल हैं:

 rand(2**256).to_s(36).ljust(8,'a')[0..7]

स्ट्रिंग के दाहिने हाथ की ओर का उपयोग करके यादृच्छिक संख्या के कम से कम महत्वपूर्ण हिस्से को हथियाने के लिए और भी बेहतर: रैंड (2 ** 64) .to_s (36) [- 10,10]
जेफ

6
SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')

डेविस से कुछ


क्यों यह स्ट्रिंग वर्णों का उपयोग कर रहा है .tr('+/=lIO0', 'pqrsxyz')?
मिगुएलकोबैन

विशेष वर्ण क्योंकि वे URL सुरक्षित नहीं हैं। और l / I या O / 0 क्योंकि वे बहुत आसान भ्रमित हैं यदि आप पठनीय उपयोगकर्ता पासवर्ड उत्पन्न करने के लिए तकनीक का उपयोग करते हैं।
ToniTornado

उस फ़ंक्शन में कुछ वर्णों के प्रति थोड़ा पूर्वाग्रह है। अन्य लंबाई (जैसे 16) के लिए भी, अंतिम वर्ण यादृच्छिक नहीं होगा। यहां उससे बचने का एक तरीका बताया गया है। सिक्योर रेंडम.बेस 6 (64) .tr ('+ / = lIO01', '') [0,16]
Shai Coleman

5

मुझे लगता है कि यह सुगमता, स्पष्टता और संशोधन में आसानी का एक अच्छा संतुलन है।

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

1
मैं इसे केवल बड़े अक्षरों / संख्याओं का उपयोग करने के लिए सलाह दूंगा, "भ्रामक" लोगों को हटा दें charset = (1..9) .to_a.concat (('A' .. 'Z')। to_a) .reject {| | [0, 1, 'O', 'I'] शामिल हैं? (A)} (0 ... size) .map {charset [rand (charset.size)]]} .join
चमक

5

बस यहाँ मेरे सेंट जोड़ने ...

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

3
NB: यह हमेशा एक स्ट्रिंग बिल्कुल + लंबाई + लंबी नहीं लौटाता है - यह छोटा हो सकता है। यह संख्या पर निर्भर करता हैrand
tardate

5

आप String#randomरूबी जेम के पहलुओं से उपयोग कर सकते हैं facets

यह मूल रूप से ऐसा करता है:

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

4

मेरा पसंदीदा है (:A..:Z).to_a.shuffle[0,8].join। ध्यान दें कि फेरबदल के लिए रूबी> 1.9 की आवश्यकता होती है।


4

इस समाधान के लिए बाहरी निर्भरता की आवश्यकता होती है, लेकिन दूसरे की तुलना में यह पूर्ववर्ती लगता है।

  1. मणि स्थापित ठग
  2. Faker::Lorem.characters(10) # => "ang9cbhoa8"

4

दिया हुआ:

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

एकल अभिव्यक्ति, एक तर्क के रूप में पारित किया जा सकता है, डुप्लिकेट वर्णों की अनुमति देता है:

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

3

मुझे राडार का जवाब सबसे अच्छा लगता है, अब तक, मुझे लगता है। मैं इस तरह से थोड़ा ट्विक करूंगा:

CHARS = ('a'..'z').to_a + ('A'..'Z').to_a
def rand_string(length=8)
  s=''
  length.times{ s << CHARS[rand(CHARS.length)] }
  s
end

उपयोग क्यों नहीं (CHARS*length).sample(length).join?
नील्स

@ हनीस यह सुझाव गैर-दोहराया पात्रों के पक्ष में एक भारित स्ट्रिंग उत्पन्न करेगा । उदाहरण के लिए, अगर CHARS=['a','b']फिर अपने विधि उत्पन्न होगा "aa"या "bb"समय का केवल 33% है, लेकिन "ab"या "ba"समय का 67%। शायद यह एक समस्या नहीं है, लेकिन यह ध्यान में रखने योग्य है!
टॉम लॉर्ड

अच्छी बात है, @TomLord, मुझे लगता है कि मुझे वास्तव में यह महसूस नहीं हुआ कि जब मैंने वह सुझाव पोस्ट किया था (हालांकि मुझे मानना ​​होगा कि मुझे यह पोस्ट याद नहीं है: D)
नील्स


3

मेरे 2 सेंट:

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


3

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)*""

प्रत्येक रेंज से एक चरित्र।

और अगर आपको प्रत्येक श्रेणी से कम से कम एक वर्ण की आवश्यकता है, जैसे कि एक यादृच्छिक पासवर्ड बनाना जिसमें एक अपरकेस, एक लोअरकेस अक्षर और एक अंक हो, तो आप कुछ इस तरह कर सकते हैं:

( ('a'..'z').to_a.sample(8) + ('A'..'Z').to_a.sample(8) + (0..9).to_a.sample(8) ).shuffle.join 
#=> "Kc5zOGtM0H796QgPp8u2Sxo1"

और यदि आप प्रत्येक श्रेणी की एक निश्चित संख्या को लागू करना चाहते हैं, तो आप कुछ इस तरह से कर सकते हैं:( ('a'..'z').to_a.sample(8) + ('A'..'Z').to_a.sample(8) + (0..9).to_a.sample(8) + [ "%", "!", "*" ].sample(8) ).shuffle.join #=> "Kc5zOGtM0*H796QgPp%!8u2Sxo1"
जोशुआ पिंटर

3

मैं हाल ही में 62 अक्षरों से 8 बाइट रैंडम स्ट्रिंग उत्पन्न करने के लिए कुछ ऐसा कर रहा था। वर्ण 0-9, एज़, एज़ेड थे। मैं उनमें से एक सरणी के रूप में 8 बार पाशन था और सरणी से एक यादृच्छिक मूल्य उठा रहा था। यह एक रेल ऐप के अंदर था।

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 उपरोक्त पंक्ति में) को बहुत अधिक बार दोहराया जा रहा था।

मैंने छोटी देरी के साथ इस उपरोक्त लाइन के 100000 पुनरावृत्तियों के माध्यम से चलाने के लिए एक स्क्रिप्ट बनाई, ताकि प्रति घंटे के आधार पर किसी प्रकार के दोहराने के पैटर्न को देखने में 3-4 घंटे लगें, लेकिन कुछ भी नहीं देखा। मुझे नहीं पता कि मेरे रेल ऐप में ऐसा क्यों हो रहा था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.