我的任務是生成一個具有以下引數的隨機字串:
- 至少一個大寫字母[/li
- 至少一個小寫 。
- 至少一個數字 。
- 不允許有重復的字符/數字(例如:不允許有aa,允許有aba,允許有Aa) 。
我能夠用1,2,3個引數生成一個隨機字串,但是引數4的邏輯卻不見了。
inputChars = [('a'...'z'), ('A'。 .'Z'),(0.9)].map(&:to_a).lattenten
string = (0...16).map { inputChars[rand(inputChars.length)] }.join
uj5u.com熱心網友回復:
require 'set'
inputChars = [('a'...'z'), ('A'. 'Z'),(0...9)].map(&:to_a) .flatten
set_string = Set.new
回圈 dobreak if set_string.size == 16
cr = inputChars[rand(inputChars.length)] 。
set_string << cr
end
output = set_string.to_a.join
我只是把你的map操作改為回圈操作,并添加Set資料結構來存盤來自隨機inputChars操作的字符。使用Set將不允許相同的字符
。uj5u.com熱心網友回復:
讓我們從定義兩個常量開始吧。
CHARS_BY_TYPE = {
lower: ('a'.'z').to_a.freeze,
upper: ('A'..'Z').to_a.freeze。
digit: ('0'..'9').to_a.freeze
}.freeze
ALL = (CHARS_BY_TYPE[:lower] CHARS_BY_TYPE[:upper] CHARS_BY_TYPE[:digit]) 。 凍結
#=> [["a", "b", ..., "z", "A", "B", ..., "Z", "0", "1", ..., "9"]/span>
最初,我將從陣列ALL中每次隨機選擇一個字符來構建一個指定長度的字串,確保沒有兩個連續的字符是相同的。然而,我們不能保證所生成的字串至少包含一個大寫字母、一個小寫字母和一個數字。
def append_random_char(last_char)
回圈do
ch = ALL.sample
break ch unless ch == last_char
結束
end
我們的主方法將按以下方式開始:
def random_string(str_len)
raise ArgumentError if str_len < 3
(str_len - 2).times.with_object('') { |_,s| s << append_random_char(s[-1] ) } if str_len <2.
# ...
end>
例如:
s = random_string(40)
#=> "arN64kDw6ClzcNMj8WAkj1NJC2B5oFoRlcXl5S"
str_len是所需的字串長度,40在這個例子中。請注意,s包含38個字符,其中沒有兩個連續的字符是相等的。我們將需要在后面添加2字符。例如,如果該字串不包含任何數字,那么添加的這兩個字符中至少有一個(在一個隨機的位置)將是一個(隨機選擇的)數字。如果字串更短,并且只包含,例如,數字,那么添加的兩個字符將是一個大寫字母和一個小寫字母。
接下來我們需要查看該字串是否缺少一個大寫字母、一個小寫字母和/或一個數字。(它不能缺少所有三個,因為字串必須至少包含三個字符。)
接下來,我們需要查看字串是否缺少一個大寫字母、小寫字母和/或一個數字。
require 'set'/span>
def types_to_add(str)
[:lower, :upper, :digit].select do |type|
st = CHARS_BY_TYPE[type].to_set
str.each_char.none? { |ch| st.include? (ch) }
end
結束。
對于上面生成的隨機字串,我們得到:
types_to_add(s)
#=> []
意思是該字串至少包含一個大寫字母、一個小寫字母和一個數字。試試這個:
types_to_add(s.gsub(/d|[A-Z]/, ''/span>)
#=> [:upper, :digit]。
見Enumerable#none?。CHARS_BY_TYPE[type]被轉換為一個集合,只是為了加速查找。
假設現在我們需要插入一個大寫字母、小寫字母或數字來滿足字串中至少有一個的要求。具體來說,我們希望在我們正在構建的字串中的隨機位置插入一個隨機抽取的字符(從
CHARS_BY_TYPE[:lower]、CHARS_BY_TYPE[:upper]或CHARS_BY_TYPE[:digit]),但限制是前面和后面的字符都不是同一個字符。
def insert_in_string(str, ch)
i = 回圈 do
i = rand(str.size 1)
next if ch == str[i] 。
break i if i.zero? || ch != str[i-1]
末尾
str.insert(i, ch)
end
例如,如果我們要在我們的字串'0(副本)中插入字符s(這不需要):
insert_in_string(s.dup, '0)
#=> "arN64kDw6ClzcN0Mj8WAkj1NJC2B5oFoRlcXl5S"
s #=> "arN64kDw6ClzcNMj8WAkj1NJC2B5oFoRlcXl5S"
^
這是在str中索引i的字符之前插入字符ch。如果rand(str.size 1)回傳str.size ch被插入在str的最后一個字符之后。
在這個操作之后,最后一步是使用方法append_random_char來構建字串,使其達到所需的長度。
完成的主方法如下。
def random_string(str_len)
raise ArgumentError if str_len < 3
s = (str_len - 2).times.with_object('') { |_,s| s << append_random_char(s[-1] ) }
types_to_add(s).each { |type| insert_in_string(s, CHARS_BY_TYPE[type].same) }
(str_len - s.size).times { s << append_random_char(s[-1] ) }
s
結束。
s = random_string(40)
#=> "PtQrVFZWUYFwiwRy3ySfAy42G1NT98J6cMVMaWeT"
s.match? (/[a-z]/)
#=> true
s.match? (/[A-Z]/)
#=> true;/span> s.match?
s.match? (/d/)
#=> true[/span]。
s.size
#=> 40
uj5u.com熱心網友回復:
這是我要做的(警告。沒有經過測驗。只是想介紹一下我的演算法的想法 我的演算法)。) 我首先為產生的隨機字串的長度取一個亂數(長度將在4到16個字符之間)。然后我確定 其中有多少是大寫字母/小寫字母/數字,根據這些決定,我生成一個字串。 這些決定,我生成字串,確保我不會得到任何重復的
uchars=('A'/span>...'Z'/span>).to_a
lchars=('a'...'z') .to_a
dchars=('0'...'9').to_a
charmap = { u: uchars, l: lchars, d: dchars }
total_length=rand(13) 4 # 要生成的字串的總長度。
total_u=rand(total_length-3) 1 # 要生成的UCHAR總數
total_l=rand(total_length-total_u-2) 1 # Total number of lchars
total_d=total_length-total_u-total_l # Total number of digits[/span
# 要生成的型別的陣列:u]*total_u [:l]*total_l [:d]*total_d).shuffle
# chartypes是一個類似于[:u,:d,:d,:l,:u]的陣列,其中
# 符號指定要生成的字符種類。
# outstr : 要生成的隨機字串
outstr = charmap[chartypes.first].sample
last_char = outstr.dup
total_length. times do |index|
回圈 do
nextchar = charmap[chartypes[index]].sample
if nextchar != last_char
outstr << nextchar
last_char = nextchar
break
end
end
end end
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/313832.html
標籤:
上一篇:使用find_or_create_by、create_with和可選鏈的Railsupsert
下一篇:活躍的資源軌道沒有取到資料
