使用Caesar Cipher时如何保留字符大小写

时间:2015-12-14 22:40:16

标签: ruby caesar-cipher

我在Ruby中有一个Caesar Cipher脚本正在工作,但它返回字符串作为所有大写字母,而不是保留原始字符串的大小写。

我可以使用capitalize使其看起来足够好,但我想要一种更具体的方法来保存案例。

这是脚本:

BASE_ORD = 'A'.ord

def caesar_cipher(phrase, key)
  cipher = phrase.gsub(/[a-z]/i) do |c|
    orig_pos = c.upcase.ord - BASE_ORD
    new_pos = (orig_pos + key) % 26
    (new_pos + BASE_ORD).chr
  end
  puts cipher
end

caesar_cipher("What a string!", 5) 

任何帮助或见解都将不胜感激。

2 个答案:

答案 0 :(得分:2)

根据您现有的代码,最简单的解决方案是检查字符是大写还是小写,并相应地设置function OnMouseEnter() { renderer.material.color = Color.grey; } 。由于小写字母位于UTF-8中的大写字母之后(如ASCII),我们只能测试base_ord,例如:

letter >= 'a'

以下是此更改的整个方法(您不再需要base_ord = (letter >= 'a' ? 'a' : 'A').ord 常量):

BASE_ORD

修改

Amadan对使用String#tr提出了一个很好的观点。这是一个更简洁的实现:

def caesar_cipher(phrase, key)
  phrase.gsub(/[a-z]/i) do |letter|
    base_ord = (letter >= 'a' ? 'a' : 'A').ord
    orig_pos = letter.ord - base_ord
    new_pos = (orig_pos + key) % 26
    (new_pos + base_ord).chr
  end
end

puts caesar_cipher("What a string!", 5) # => Bmfy f xywnsl!

答案 1 :(得分:1)

如评论中所述,tr更容易用于Caesar Cypher(一旦你准备好两个字母表),也应该更快:

class CaesarCypher
    def initialize(key, alphabet=nil)
        @from_alphabet = alphabet || (?a..?z).to_a.join
        @to_alphabet = @from_alphabet[key..-1] + @from_alphabet[0...key]
        @from_alphabet += @from_alphabet.upcase
        @to_alphabet += @to_alphabet.upcase
    end
    def encode(str)
        str.tr(@from_alphabet, @to_alphabet)
    end
    def encode!(str)
        str.tr!(@from_alphabet, @to_alphabet)
    end
    def decode(str)
        str.tr(@to_alphabet, @from_alphabet)
    end
    def decode(str)
        str.tr!(@to_alphabet, @from_alphabet)
    end
end

cc = CaesarCypher.new(1)
puts cc.encode("Caesar, huh?")
puts cc.decode("Dbftbs, ivi?")