如何在Ruby中实现Caesar Cipher?

时间:2016-12-26 19:54:33

标签: ruby

我在theOdinProject学习Ruby,我需要构建Caeser Cipher。这是我的代码:

    def caesar_cipher plaintext, factor
    codepoints_array = []
    ciphertext = ""

    plaintext.split('').each do |letter|
        if letter =~ /[^a-zA-Z]/
            codepoints_array << letter.bytes.join('').to_i
        else
            codepoints_array << letter.bytes.join('').to_i + factor
        end
    end
    ciphertext = codepoints_array.pack 'C*'
    puts ciphertext
end
caesar_cipher("What a string!", 5)

我打赌它不是真的&#34;优雅&#34;但这里的主要问题是输出应该是&#34; Bmfy f xywnsl!&#34;但我有什么&#34; \ mfy f xywnsl!&#34;。我现在已经在这项任务中苦苦挣扎了几天,但我仍然不知道如何&#34;链接&#34;字母表这样&#39; z&#39;成为&#39; a&#39;因子== 1。

我可以在OdinProject上检查其他人的完成任务,但他们的代码通常不同/更专业,我试图得到一个提示,而不是最终的解决方案。如果有人能暗示我如何解决这个问题,我会非常感激。提前谢谢。

1 个答案:

答案 0 :(得分:1)

提示

如果ASCII table只有26个字符,那么您的代码几乎可以正常工作。

W不是wz后来的是{,而不是a

因此,您首先需要将downcase应用于您的字母,偏移字节码以使a为0,并执行每次计算modulo 26。

修改版

def caesar_cipher plaintext, factor
  codepoints_array = []
  ciphertext = ""

  a_codepoint = 'a'.ord

  plaintext.split('').each do |letter|
    if letter =~ /[^a-zA-Z]/
      codepoints_array << letter.bytes.join('').to_i
    else
      shifted_codepoint = letter.downcase.bytes.join('').to_i + factor
      codepoints_array << (shifted_codepoint - a_codepoint) % 26 + a_codepoint
    end
  end
  ciphertext = codepoints_array.pack 'C*'
  ciphertext
end

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

另一种解决方案

我刚才为Vigenere chiper写了一个小的Ruby脚本。凯撒密码只是它的变种,每个角色都有相同的因素:

class Integer
  # 0 => 'a', 1 => 'b', ..., 25 => 'z', 26 => 'a'
  def to_letter
    ('a'.ord + self % 26).chr
  end
end

class String
  # 'A' => '0', 'a' => 0, ..., 'z' => 25
  def to_code
    self.downcase.ord - 'a'.ord
  end
end

def caesar_cipher(string, factor)
  short_string = string.delete('^A-Za-z')
  short_string.each_char.map do |char|
    (char.to_code + factor).to_letter
  end.join
end

puts caesar_cipher("What a string!", 5) #=> "bmfyfxywnsl"
puts caesar_cipher("bmfyfxywnsl", -5)   #=> "whatastring"

使用密码,建议删除任何标点符号或空格,因为它们可以更容易地使用统计分析对字符串进行解码。

无论如何,凯撒密码非常弱。