如何只影响字母,而不影响凯撒密码中的标点符号
How to affect only letters, not punctuation in Caesar Cipher code
我正在尝试在 Ruby 中编写凯撒密码,但在尝试仅将字母更改为数值而不是标点符号时遇到了障碍。
到目前为止,这是我的脚本:
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)
我尝试使用 select
,但我不知道如何 select 仅标点符号或字母。
使用String#gsub
仅匹配您要替换的字符。在本例中,它是字母表中的字母,因此您将使用正则表达式 /[a-z]/i
.
您可以将一个块传递给 gsub
,它将为字符串中的每个匹配项调用,块的 return 值将用作替换。例如:
"Hello, world!".gsub(/[a-z]/i) {|chr| (chr.ord + 1).chr }
# => Ifmmp, xpsme!"
这是您的凯撒密码方法的一个非常有效的版本:
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?"
编辑:
%
就是modulo operator。这里用来使new_pos
"wrap around"到字母表的开头,如果它大于25.
例如,假设letter
是"Y"
,key
是5。"Y"在字母表中的位置是24(假设"A"是0), 所以 orig_pos + key
将是 29, 超过了字母表的末尾。
一个解决方案是:
new_pos = orig_pos + key
if new_pos > 25
new_pos = new_pos - 26
end
这将使 new_pos
3 对应于字母 "D," 成为正确的结果。然而,我们可以更有效地得到相同的结果,方法是将“29 modulo 26”——在 Ruby(以及许多其他语言)中表示为 29 % 26
——其中 returns运算的余数为 29 ÷ 26。(因为字母表中有 26 个字母)。 29 % 26
为3,同上结果
除了将数字限制在一定范围内,就像我们在这里所做的那样,模运算符还经常用于测试一个数字是否可以被另一个数字整除。例如,您可以通过测试 n % 3 == 0
.
来检查 n
是否可以被 3 整除
我正在尝试在 Ruby 中编写凯撒密码,但在尝试仅将字母更改为数值而不是标点符号时遇到了障碍。
到目前为止,这是我的脚本:
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)
我尝试使用 select
,但我不知道如何 select 仅标点符号或字母。
使用String#gsub
仅匹配您要替换的字符。在本例中,它是字母表中的字母,因此您将使用正则表达式 /[a-z]/i
.
您可以将一个块传递给 gsub
,它将为字符串中的每个匹配项调用,块的 return 值将用作替换。例如:
"Hello, world!".gsub(/[a-z]/i) {|chr| (chr.ord + 1).chr }
# => Ifmmp, xpsme!"
这是您的凯撒密码方法的一个非常有效的版本:
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?"
编辑:
%
就是modulo operator。这里用来使new_pos
"wrap around"到字母表的开头,如果它大于25.
例如,假设letter
是"Y"
,key
是5。"Y"在字母表中的位置是24(假设"A"是0), 所以 orig_pos + key
将是 29, 超过了字母表的末尾。
一个解决方案是:
new_pos = orig_pos + key
if new_pos > 25
new_pos = new_pos - 26
end
这将使 new_pos
3 对应于字母 "D," 成为正确的结果。然而,我们可以更有效地得到相同的结果,方法是将“29 modulo 26”——在 Ruby(以及许多其他语言)中表示为 29 % 26
——其中 returns运算的余数为 29 ÷ 26。(因为字母表中有 26 个字母)。 29 % 26
为3,同上结果
除了将数字限制在一定范围内,就像我们在这里所做的那样,模运算符还经常用于测试一个数字是否可以被另一个数字整除。例如,您可以通过测试 n % 3 == 0
.
n
是否可以被 3 整除