Ruby 数组元素
Ruby Array Elements
我正在尝试在 ruby 中创建密码生成。目前一切正常,只是卡在了生成密码的最后一步。
我问用户 he/she 是否希望密码包含数字、小写或大写。
如果是,用户将为否输入 1 和 0。
如果一切都是 1,我使用下面的代码生成密码。这意味着用户想要包括数字,小写和大写。
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10)
end
p passGen
这在 90% 的时间都有效。 10% 的情况下,生成的密码不会包含任何数字。但其他一切都存在。我不确定这是否是因为从中采样密码的数组的大小或长度。
不管怎样,让我们进入下面的主要问题
问题出在这里,如果一个或多个输入为 0,我很难编写生成密码的代码。那是因为用户不想包含数字。或者没有数字和大写等。因为我无法预测用户可能想要或不想要什么。我需要这方面的帮助。
谢谢。
您需要使输入数组更加动态:
passGen = []
passGen += (0..9).to_a if numbers == 1
passGen += ('A'..'Z').to_a if uppercase == 1
passGen += ('a'..'z').to_a if lowercase == 1
passGen.sample(10).join
现在,要解决丢失字符的其他问题 - 这是因为您只是从数组中随机取出 10 个字符。所以它可以只取,例如,所有数字。
为了解决这个问题,您需要先从每个生成器中获取一个字符,然后随机生成剩余的字符并将结果打乱:
def generators(numbers:, lowercase:, uppercase:)
[
(0..9 if numbers),
('A'..'Z' if uppercase),
('a'..'z' if lowercase)
].compact.map(&:to_a)
end
def generate_password(generators:, length:, min_per_generator: 1)
chars = generators.flat_map {|g| Array.new(min_per_generator) { g.sample }}
chars += Array.new(length - chars.length) { generators.sample.sample }
chars.shuffle.join
end
gens = generators(numbers: numbers == 1, uppercase == 1, lowercase: lowercase == 1)
Array.new(10) { generate_password(generators: gens, length: 10) }
代码不知道它需要包含来自每个组的 digit/letter。该样本采用随机符号,并且由于您基本上是抽样 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
,所以有可能所有符号都不是数字。
修复它的最简单方法是检查“密码”中是否有来自每个组的符号,然后用不存在的组中的符号替换随机符号。
如果我要编写这个程序,我会那样做
def random_from_range(range)
range.to_a.sample.to_s
end
def passGen(numbers, lowercase, uppercase)
result = ''
possibleSigns = []
if numbers == 1
range = (0..9)
result += random_from_range(range)
possibleSigns += range.to_a
end
if lowercase == 1
range = ('A'..'Z')
result += random_from_range(range)
possibleSigns += range.to_a
end
if uppercase == 1
range = ('a'..'z')
result += random_from_range(range)
possibleSigns += range.to_a
end
desired_lenth = 10
while result.length < desired_lenth
result += possibleSigns.sample.to_s
end
result
end
puts passGen(1,1,1)
通过说 (0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a
,您正在创建一个包含 10 + 26 + 26 = 62 个元素的数组,然后您只从中选择 10 个元素。
在你那里,我将围绕 until
块生成密码:
def generate_password_with_digits_and_caps
[(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = generate_password_with_digits_and_caps
end
这也可以工作(更接近您的代码段):
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
end
从一些简单而愚蠢的事情开始:
passGen = (('0'..'9').to_a.sample(1)+ ('A'..'Z').to_a.sample(1)+('a'..'z').to_a.sample(8).shuffle).join
从技术上讲,这已经满足您的要求。从美观和安全的角度来看,这里的缺点是大写字符的个数始终为 8。更优雅的解决方案是找到三个非零整数加起来为 10,并且可以用作参数sample
电话。此外,如果没有请求数字,您只需将 0
作为参数传递给 sample
.
因为这超出了你的提问范围,我也不知道你想不想问到这里,这里就不多说了。
我正在尝试在 ruby 中创建密码生成。目前一切正常,只是卡在了生成密码的最后一步。
我问用户 he/she 是否希望密码包含数字、小写或大写。 如果是,用户将为否输入 1 和 0。
如果一切都是 1,我使用下面的代码生成密码。这意味着用户想要包括数字,小写和大写。
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10)
end
p passGen
这在 90% 的时间都有效。 10% 的情况下,生成的密码不会包含任何数字。但其他一切都存在。我不确定这是否是因为从中采样密码的数组的大小或长度。
不管怎样,让我们进入下面的主要问题
问题出在这里,如果一个或多个输入为 0,我很难编写生成密码的代码。那是因为用户不想包含数字。或者没有数字和大写等。因为我无法预测用户可能想要或不想要什么。我需要这方面的帮助。 谢谢。
您需要使输入数组更加动态:
passGen = []
passGen += (0..9).to_a if numbers == 1
passGen += ('A'..'Z').to_a if uppercase == 1
passGen += ('a'..'z').to_a if lowercase == 1
passGen.sample(10).join
现在,要解决丢失字符的其他问题 - 这是因为您只是从数组中随机取出 10 个字符。所以它可以只取,例如,所有数字。
为了解决这个问题,您需要先从每个生成器中获取一个字符,然后随机生成剩余的字符并将结果打乱:
def generators(numbers:, lowercase:, uppercase:)
[
(0..9 if numbers),
('A'..'Z' if uppercase),
('a'..'z' if lowercase)
].compact.map(&:to_a)
end
def generate_password(generators:, length:, min_per_generator: 1)
chars = generators.flat_map {|g| Array.new(min_per_generator) { g.sample }}
chars += Array.new(length - chars.length) { generators.sample.sample }
chars.shuffle.join
end
gens = generators(numbers: numbers == 1, uppercase == 1, lowercase: lowercase == 1)
Array.new(10) { generate_password(generators: gens, length: 10) }
代码不知道它需要包含来自每个组的 digit/letter。该样本采用随机符号,并且由于您基本上是抽样 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
,所以有可能所有符号都不是数字。
修复它的最简单方法是检查“密码”中是否有来自每个组的符号,然后用不存在的组中的符号替换随机符号。
如果我要编写这个程序,我会那样做
def random_from_range(range)
range.to_a.sample.to_s
end
def passGen(numbers, lowercase, uppercase)
result = ''
possibleSigns = []
if numbers == 1
range = (0..9)
result += random_from_range(range)
possibleSigns += range.to_a
end
if lowercase == 1
range = ('A'..'Z')
result += random_from_range(range)
possibleSigns += range.to_a
end
if uppercase == 1
range = ('a'..'z')
result += random_from_range(range)
possibleSigns += range.to_a
end
desired_lenth = 10
while result.length < desired_lenth
result += possibleSigns.sample.to_s
end
result
end
puts passGen(1,1,1)
通过说 (0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a
,您正在创建一个包含 10 + 26 + 26 = 62 个元素的数组,然后您只从中选择 10 个元素。
在你那里,我将围绕 until
块生成密码:
def generate_password_with_digits_and_caps
[(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = generate_password_with_digits_and_caps
end
这也可以工作(更接近您的代码段):
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
end
从一些简单而愚蠢的事情开始:
passGen = (('0'..'9').to_a.sample(1)+ ('A'..'Z').to_a.sample(1)+('a'..'z').to_a.sample(8).shuffle).join
从技术上讲,这已经满足您的要求。从美观和安全的角度来看,这里的缺点是大写字符的个数始终为 8。更优雅的解决方案是找到三个非零整数加起来为 10,并且可以用作参数sample
电话。此外,如果没有请求数字,您只需将 0
作为参数传递给 sample
.
因为这超出了你的提问范围,我也不知道你想不想问到这里,这里就不多说了。