如何在Ruby中实现Caesar密码?

如何在Ruby中实现Caesar密码?,ruby,Ruby,我正在学习Rubyon,我需要构建Caeser密码。这是我的密码: def caesar_cipher plaintext, factor codepoints_array = [] ciphertext = "" plaintext.split('').each do |letter| if letter =~ /[^a-zA-Z]/ codepoints_array << letter.bytes.join

我正在学习Rubyon,我需要构建Caeser密码。这是我的密码:

    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)
def caesar_密码明文,系数
码点_数组=[]
密文=“”
纯文本。拆分(“”)。每个do字母|
如果字母=~/[^a-zA-Z]/
码点数组提示
如果代码只有26个字符,那么代码几乎可以正常工作

但是
W
不是
W
,在
z
之后是
{
,而不是
a

因此,首先需要对字母进行应用,偏移字节码,使
a
为0,然后进行每次计算

修改版 对于密码,建议删除任何标点符号或空格,因为它们使使用统计分析对字符串进行解码更加容易


Caesar密码很弱。

提示:看一看a,然后研究当你将因子
5
添加到
W
的字节中时,你得到了什么字符(通过它的数字)。然后看看你需要如何更改字节值以获得期望的字符…
ord
字节相同。连接(“”).to_i
'a'。最多('z')。循环。首先(52)
是字母表两次。谢谢你的回答。幸好我理解你的代码。幸好我可能永远不会想到这个主意。关于如何保持相同的情况,有什么想法吗?(因为这是任务的一部分-我想我应该早点澄清这一点:))在Ruby中,总是有100种方法可以编写同一段代码。请参阅TIMTOADY()。这里有另一种方法可以保留大小写:请注意,密码保留空格和大小写是一个非常糟糕的主意。
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!"
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"