Ruby 如何在凯撒密码中仅影响字母而不影响标点符号
我正试图用Ruby编写一个Caesar密码,但在尝试将字母改为数值而不是标点符号时遇到了一个障碍 以下是我目前的脚本:Ruby 如何在凯撒密码中仅影响字母而不影响标点符号,ruby,caesar-cipher,Ruby,Caesar Cipher,我正试图用Ruby编写一个Caesar密码,但在尝试将字母改为数值而不是标点符号时遇到了一个障碍 以下是我目前的脚本: def caesar_cipher(phrase, key) array = phrase.split("") number = array.map {|n| n.upcase.ord - (64-key)} puts number end puts "Script running" caesar_cipher("Hey what's
def caesar_cipher(phrase, key)
array = phrase.split("")
number = array.map {|n| n.upcase.ord - (64-key)}
puts number
end
puts "Script running"
caesar_cipher("Hey what's up", 1)
我尝试使用选择
,但我不知道如何仅选择标点符号或字母。仅用于匹配要替换的字符。在本例中,它是字母表中的字母,因此您将使用正则表达式/[a-z]/i
您可以将块传递给gsub
,该块将为字符串中的每个匹配项调用,并且块的返回值将用作替换。例如:
"Hello, world!".gsub(/[a-z]/i) {|chr| (chr.ord + 1).chr }
# => Ifmmp, xpsme!"
下面是一个非常有效的Caesar密码方法版本:
BASE_ORD = 'A'.ord
def caesar_cipher(phrase, key)
phrase.gsub(/[a-z]/i) do |letter|
orig_pos = letter.upcase.ord - BASE_ORD
new_pos = (orig_pos + key) % 26
(new_pos + BASE_ORD).chr
end
end
caesar_cipher("Hey, what's up?", 1) # => "IFZ, XIBU'T VQ?"
编辑:
%
是最重要的。在这里,如果大于25,则用于将新建\u pos
“环绕”到字母表的开头
例如,假设字母
为“Y”
,键
为5。字母表中“Y”的位置为24(假设“A”为0),因此orig_pos+key
将为29,超过字母表的末尾
一种解决办法是:
new_pos = orig_pos + key
if new_pos > 25
new_pos = new_pos - 26
end
这将使对应于字母“D”的新位置成为正确的结果。但是,我们可以更有效地获得相同的结果,方法是将“29 26”——用Ruby(和许多其他语言)表示为29%26
——返回操作29÷26的剩余部分。(因为字母表中有26个字母)<代码>29%26为3,结果与上面相同
除了像我们在这里所做的那样将一个数限制在某个范围之外,模算子还经常用于测试一个数是否可以被另一个数整除。例如,您可以通过测试
n%3==0
来检查n
是否可被3整除,谢谢!gsub肯定在努力省去标点符号!你的解决方案中有几点我不明白,你介意解释一下吗?在%26之前我都能理解,这有什么用?另外,当我运行脚本时,我会得到一个数组,而不是显示“IFZ,XIBU'T VQ?”的字符串。我编辑了我的答案,以解释模(%
)运算符gsub
总是返回一个字符串,所以我不确定为什么会得到一个数组。