【问题标题】:Creating a Cipher Code in Ruby在 Ruby 中创建密码
【发布时间】:2017-09-23 03:29:00
【问题描述】:

我的任务是为我正在进行的项目创建凯撒密码。凯撒密码获取文本字符串中的每个字母,并将其替换为距离它固定数量的字母(由密码密钥决定)。例如,如果我的文本是“cat”并且我的密钥是 3,那么我的新单词将是“fdw”(我假设正数将字母向右移动)。我已经能够让我的代码正确解决大多数文本字符串,但我发现如果我的字符串包含 > ?或@它不起作用。如果有帮助,他们的 ASCII 代码是 62,63 和 64。任何意见表示赞赏!

def caesar_cipher(str, num)
strArray = str.split('')

cipherArray = strArray.collect do |letter|
 letter = letter.ord

  if (65...90).include?(letter + num) || (97...122).include?(letter + num)
    letter = letter + num
  elsif (91...96).include?(letter + num) || (123...148).include?(letter + num)
    letter = (letter - 26) + num
  else
    letter
  end

end

 cipherArray = cipherArray.collect {|x| x.chr}
 cipher = cipherArray.join('')

end


caesar_cipher("Am I ill-prepared for this challenge?", 3)
#ord 62-64 DON'T work >, ?, @

【问题讨论】:

  • 您认为>?@三个字母对的字符有哪些?
  • @spickermann 嗨!我为每个符号使用了 ASCii 代码。使用它,> 等于 62,?等于 63,@ 等于 64。每个加 3 将得到 65(“A”)、66(“B”)和 67(“C”)。

标签: ruby-on-rails ruby


【解决方案1】:

您应该创建一个字母变量,如果您使用两端,那么您将遇到两个问题:负数和不存在的 ASCii 数。您可以使用模块运算符 % 或单次减法来处理此问题。

alphabet = "abcde"

text_to_cipher= "aaee" => 0044 #number based in his position at aphabet var
key = 3

结果将是 3377 => dd¡或任何其他符号,因为 7 超出字符串长度“abcde”,ASCii 在其末端也会发生同样的情况。 使用模块运算符,您可以限制它。

size_of_your_alphabet = 5 # For this case
7%size_of_your_alphabet = 2

【讨论】:

    【解决方案2】:

    Ruby 内置 tr 是实现替换密码的理想选择。

    第 1 步:组装您要转换的角色。

    chars = ["A".."Z", "a".."z", ">".."@"].flat_map(&:to_a)
    

    第 2 步:创建一个 1:1 转换字符数组

    transformed = chars.map{|c| (c.ord + 3).chr}
    

    第 3 步:应用tr 转换字符串。

    str.tr(chars.join, transformed.join)
    

    完整的工作示例:

    def caesar_cipher(str, num)
      chars = ["A".."Z", "a".."z", ">".."@"].flat_map(&:to_a)
      transformed = chars.map{|c| (c.ord + num).chr}
      str.tr(chars.join, transformed.join)
    end
    

    输出:

    > caesar_cipher("Am I ill-prepared for this challenge?", 3)
    #=> "Dq L mpp-tvitevih jsv xlmw gleppirkiC"
    

    注意事项:

    • 大多数替换密码实际上依赖于字母轮换,而不是 ASCII 值。我最初的假设是你想要一个轮换,例如("a".."z").to_a.rotate(num)。请参阅先前的编辑以获取一个工作示例。
    • 您可以使用tr() 中的范围来创建一个非常简单的凯撒密码:str.tr('A-Za-z','B-ZAb-za')
    • 编辑:此外,由于范围规范功能,\ 是一个转义字符,因此您可以使用像 - 这样的文字。有关详细信息,请参阅this SO answer。我认为上面显示了一个错误,因为它包含一个 \ 应该被另一个 \ 转义。

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      相关资源
      最近更新 更多