使用next
,我创建了一个方法,通过向前推进一个字母的每个字母来加密密码:
def encryptor
puts "Give me your password!"
password = gets.chomp
index = 0
while index < password.length
password[index] = password[index].next!
index +=1
end
puts password
end
encryptor
我必须创建一个解除它的解密方法。最后,这应该被清除:
encrypt("abc") should return "bcd"
encrypt("zed") should return "afe"
decrypt("bcd") should return "abc"
decrypt("afe") should return "zed"
我看到Ruby没有倒退的方法。我坚持使用倒车信件。我试图在方法中添加一个字母到索引,但我无法做到这一点。
非常感谢任何正确方向的帮助。
答案 0 :(得分:6)
我知道你可以使用
.next
来推进字符串。
嗯,有点,但有一些特殊情况需要注意:
'z'.next #=> 'aa'
我成功地做到了这一点
不完全是,您的encryptor
地图"xyz"
到"yzab"
。
我看到Ruby没有这个选项可以倒退。
举个例子:
'9'.next #=> '10'
'09'.next #=> '10'
如您所见,映射不是单射的。 '9'
和'09'
都映射到'10'
。因此,没有String#pred
- '10'.pred
会返回什么?
现在我完全坚持用一封信来扭转它。
您可以使用tr
:(两者都用于加密和解密)
'abc'.tr('abcdefghijklmnopqrstuvwxyz', 'zabcdefghijklmnopqrstuvwxy')
#=> 'zab'
tr
也有字符范围的 c1-c2 表示法,因此可以缩写为:
'abc'.tr('a-z', 'za-y')
#=> 'zab'
或通过Range#to_a
,join
和rotate
:
from = ('a'..'z').to_a.join #=> "abcdefghijklmnopqrstuvwxyz"
to = ('a'..'z').to_a.rotate(-1).join #=> "zabcdefghijklmnopqrstuvwxy"
'abc'.tr(from, to)
#=> "zab"
另一种选择是定义两个字母:
from = ('a'..'z').to_a
#=> ["a", "b", "c", ..., "x", "y", "z"]
to = from.rotate(-1)
#=> ["z", "a", "b", ..., "w", "x", "y"]
通过zip
创建哈希:
hash = from.zip(to).to_h
#=> {"a"=>"z", "b"=>"a", "c"=>"b", ..., "x"=>"w", "y"=>"x", "z"=>"y"}
可以传递给gsub
:
'abc'.gsub(/[a-z]/, hash)
#=> "zab"
您还可以通过Regexp::union
以编程方式构建正则表达式:
Regexp.union(hash.keys)
#=> /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/
答案 1 :(得分:1)
只要您测试.next
,就可以使用z
执行此操作:
> 'abc'.split("").map { |ch| ch=='z' ? 'a' : ch.next }.join
=> "bcd"
> 'zed'.split("").map { |ch| ch=='z' ? 'a' : ch.next }.join
=> "afe"
然后对于解密你可以这样做:
> "bcd".split("").map { |ch| ch=='a' ? 'z' : (ch.ord-1).chr }.join
=> "abc"
> "afe".split("").map { |ch| ch=='a' ? 'z' : (ch.ord-1).chr }.join
=> "zed"
最佳