我该怎么回信?

时间:2017-08-11 04:04:58

标签: ruby string

使用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没有倒退的方法。我坚持使用倒车信件。我试图在方法中添加一个字母到索引,但我无法做到这一点。

非常感谢任何正确方向的帮助。

2 个答案:

答案 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_ajoinrotate

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"

最佳