2017-08-11 30 views
0

使用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

提示:搜索「凱撒密碼」。另外,你當前的'encryptor'實現不太正確。嘗試將''zzz「'傳遞給你的方法,看看會發生什麼。 –

回答

6

我知道您可以使用.next在字符串中前進。

嗯,善良的,但也有你必須要知道的特殊情況:我這樣做是成功的

不太,你encryptor映射"xyz"

'z'.next #=> 'aa' 

"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,joinrotate

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/ 
+2

或'a-z'.split('')。rotate(-1).join'使一個目標更清晰 – mudasobwa

+0

不要忘記'ord/chr'。 –

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" 

最佳

+0

請注意,您也可以使用['Integer#pred'](http://ruby-doc.org/core-2.4.1/Integer.html#method-i-pred),即'ch.ord.pred.chr' 。一個可惜的是沒有'String#pred'雖然:( –