如果你的代码出现了奇奇怪怪的符号,比如下面这两个(这个用的是样例)
WheXetNeXeiYa]OllZhereiYawa_
Whe襡t萫襡i觓咨ll詇erei觓wa
能做到这里的想必已经找到正确的做法了,并且还考虑了特判,但是问题就出在特判上面
你的代码是不是这样写的
// m表示原文,c表示密文,mov表示位移的距离
m += (char)(c[i] - mov);
if( m[i] < 'A' && m[i] > 'Z' )
// 看位移后的字符在不在'A'到'Z'中,如果不在就纠正回来
m[i] += 'Z';
else if( m[i] < 'a' && m[i] > 'z' )
// 同上
m[i] += 'z';
这种结果对应的代码忽略了一种情况
先看下ASCII表的部分
| 十进制 | 对应字符 |
|---|---|
| 89 | Y |
| 90 | Z |
| 91 | [ |
| 92 | \ |
| 93 | ] |
| 94 | ^ |
| 95 | _ |
| 96 | ` |
| 97 | a |
| 98 | b |
由表不难看出,Z和a之间的差值根本就到不了26!!!(甚至连10都没有)
之所以出现这种情况,是因为我们假想需要特判的挪位字母减去移动值后(举个栗子,密文对应的是'b',密码对应的是'h')得到的结果必然不会是字母,从而忽略了小写字母移位到大写字母的情况!!!('b'按照'h'回移得到的是'V',注意大小写)
这就解释了“Where”为什么变成了“WheXe”之类的情况
你的代码是不是这样写的
// 相关的定义和上面的是一样的
m += (char)(c[i] - mov);
if( (m[i] < 'A' || m[i] > 'Z') && ( c[i] >= 'A' && c[i] <= 'Z') )
// 如果m[i]不在A到Z里面但是c[i]在
m[i] += 'Z';
else if( (m[i] < 'a' || m[i] > 'z') && ( c[i] >= 'a' && c[i] <= 'z') )
// 同上
m[i] += 'z';
这个时候确实考虑到上面的情况了,但是你忽略了一个问题:位移应该怎么挪?挪动的位置是相对'\0'呢还是'A'或者'a'呢?
所以,这里的赋值语句应该改为m[i] += 'Z' - 'A' + 1; (不理解为什么加1的自己可以调试一下,用样例就可以)
当然,这里只是写了上面那个分支的,下面的同理,这里就不过多赘述了