Ruby编写凯撒密码程序如何保留非字母符号不被修改?
凯撒密码非字母字符保留实现方案
现有代码问题
- 对输入全量转小写后仅保留首字母大写,丢失了原有字符串的大小写信息
- 未区分字母与非字母字符,所有字符统一执行位移操作,导致标点、空格等符号也被修改
- 没有处理字母位移溢出问题,比如
z加1后不会自动回到a,会生成非字母字符
修改后的实现代码
def caesar_cypher(phrase, number=0) # 位移值取26的模,避免大于26的数值重复位移 shift = number % 26 result = phrase.chars.map do |char| case char when 'a'..'z' shifted = char.ord + shift shifted > 'z'.ord ? (shifted - 26).chr : shifted.chr when 'A'..'Z' shifted = char.ord + shift shifted > 'Z'.ord ? (shifted - 26).chr : shifted.chr else # 非字母字符直接返回原字符 char end end.join p result end caesar_cypher("Hello world!", 4) # 输出结果:"Lipps asvph!" caesar_cypher("What a string!", 6) # 输出结果:"Cngz g yzxotm!"
核心修改点说明
- 移除了全量转小写和末尾首字母大写的逻辑,保留字符串原始的大小写格式
- 新增字符范围判断,仅对大小写字母执行位移操作,空格、感叹号等非字母字符直接原样返回
- 新增位移溢出处理,位移后超出对应大小写字母范围时,减去26(英文字母总数量)实现字母表循环效果
- 提前对位移值取模,就算输入超过26的位移值也能得到正确结果
内容的提问来源于stack exchange,提问作者George Barda
相关产品推荐
相关产品推荐

