构建一个Rot方法来解决加密问题。我有一些工作,但取出空格和任何包含的字符。打算使用bytes
代替chars
,然后在我有字节代码后将其转回字符串,但我似乎无法使其正常工作。您将如何从这段代码中保留这些内容:
码
def rot(x, string, encrypt=true)
alphabet = Array("A".."Z") + Array("a".."z")
results = []
if encrypt == true
key = Hash[alphabet.zip(alphabet.rotate(x))]
string.chars.each do |i|
if ('a'..'z').include? i
results << key.fetch(i).downcase
elsif ('A'..'Z').include? i
results << key.fetch(i).upcase
end
end
return results.join
else
key_false = Hash[alphabet.zip(alphabet.rotate(26 - x))]
string.chars.each do |i|
if ('a'..'z').include? i
results << key_false.fetch(i).downcase
elsif ('A'..'Z').include? i
results << key_false.fetch(i).upcase
end
end
return results.join
end
end
puts rot(10, "Hello, World")
=> RovvyGybvn
puts rot(10, "Rovvy, Gybvn", false)
=> HelloWorld
提前感谢您的帮助!
答案 0 :(得分:2)
只需添加if
阻止else
这样的条件:
if ('a'..'z').include? i
# ...
elsif ('A'..'Z').include? i
# ...
else
results << i
end
将所有非A-z字符添加到输出中。
答案 1 :(得分:0)
我注意到您的代码存在一些问题:
这是最大的问题 - 您的替换哈希被破坏了。我使用较小的字母表进行演示,但这也适用于26个字符:
uppercase = Array("A".."C")
lowercase = Array("a".."c")
alphabet = uppercase + lowercase
#=> ["A", "B", "C", "a", "b", "c"]
您可以通过以下方式构建替换哈希:
x = 1
key = Hash[alphabet.zip(alphabet.rotate(x))]
#=> {"A"=>"B", "B"=>"C", "C"=>"a", "a"=>"b", "b"=>"c", "c"=>"A"}
"C"=>"a"
和"c"=>"A"
指的是错误的字符大小写。这是因为您一次旋转整个字母表:
alphabet #=> ["A", "B", "C", "a", "b", "c"]
alphabet.rotate(x) #=> ["B", "C", "a", "b", "c", "A"]
相反。你必须分别旋转大写和小写字母 :
uppercase #=> ["A", "B", "C"]
uppercase.rotate(x) #=> ["B", "C", "A"]
lowercase #=> ["a", "b", "c"]
lowercase.rotate(x) #=> ["B", "C", "A"]
然后连接旋转的部分。之一:
key = Hash[uppercase.zip(uppercase.rotate(x)) + lowercase.zip(lowercase.rotate(x))]
#=> {"A"=>"B", "B"=>"C", "C"=>"A", "a"=>"b", "b"=>"c", "c"=>"a"}
或:
key = Hash[(uppercase + lowercase).zip(uppercase.rotate(x) + lowercase.rotate(x))]
#=> {"A"=>"B", "B"=>"C", "C"=>"A", "a"=>"b", "b"=>"c", "c"=>"a"}
回到完整的字母:
uppercase = Array("A".."Z")
lowercase = Array("a".."z")
x = 10
key = Hash[uppercase.zip(uppercase.rotate(x)) + lowercase.zip(lowercase.rotate(x))]
有一个可用的替换哈希使得替换字符几乎是微不足道的:
string = "Hello, World!"
result = ""
string.each_char { |char| result << key.fetch(char, char) }
result
#=> "Rovvy, Gybvn!"
我已将result
从数组更改为字符串。它还有<<
方法,之后您不必join
。
Hash#fetch
的工作方式几乎与Hash#[]
类似,但如果在哈希中找不到密钥,则可以传递返回的默认值:
key.fetch("H", "H") #=> "R" (replacement value)
key.fetch("!", "!") #=> "!" (default value)
您正在复制大量代码来处理解密部分。但是有一种更简单的方法 - 只需改变方向:
rot(10, "Hello") #=> "Rovvy"
rot(10, "Rovvy", false) #=> "Hello"
rot(-10, "Rovvy") #=> "Hello"
所以在你的代码中,你可以写:
x = -x unless encrypt
def rot(x, string, encrypt = true)
uppercase = Array("A".."Z")
lowercase = Array("a".."z")
x = -x unless encrypt
key = Hash[uppercase.zip(uppercase.rotate(x)) + lowercase.zip(lowercase.rotate(x))]
result = ""
string.each_char { |char| result << key.fetch(char, char) }
result
end
rot(10, "Hello, World!") #=> "Rovvy, Gybvn!"
rot(10, "Rovvy, Gybvn!", false) #=> "Hello, World!"