简体   繁体   English

C中的凯撒密码,大写和小写

[英]Caesar cipher in C, upper and lower case

I have to produce Caesar cipher decoder -- for both lower and upper case, but I am not able to think of an easy solution to do this (or at the moment even working one). 我必须为小写和大写都产生Caesar密码解码器,但是我无法想到一个简单的解决方案来做到这一点(或者目前甚至无法工作)。

At the moment I have this loop to decipher the code by given shift i : 目前,我有这个循环通过给定的移位i来解密代码:

char* s1 = "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop";
int s1s = strlen(s1);
int i = 16;
char tmp[s1s+1];
for (int j = 0; j < s1s; ++j) {
    char tmp_s = (char) ((int) s1[j]-i);
    if(tmp_s<65){
        tmp_s+=58;
    }
    tmp[j]=tmp_s;
}
tmp[s1s]='\0';

Output should be abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ , at the moment it is abcdefghijklmnopqrstuvwxyzABCDEFGHIJQRSTUVWXYZ[\\]^_ . 输出应为abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,目前为abcdefghijklmnopqrstuvwxyzABCDEFGHIJQRSTUVWXYZ[\\]^_

I have tried some conditions, but can't really figure out the right one. 我已经尝试了一些条件,但无法真正找到合适的条件。

Your tests are not complete. 您的测试未完成。 Consider the "ASCII space": 考虑“ ASCII空间”:

\0 ... 'A' ... 'Z' ... 'a' ... 'z' ...

You have here 5 areas: 您在这里有5个领域:

  1. characters before 'A'. “ A”之前的字符。
  2. characters between 'A' and 'Z'. “ A”和“ Z”之间的字符。
  3. characters between 'Z' and 'a'. “ Z”和“ a”之间的字符。
  4. characters between 'a' and 'z'. “ a”和“ z”之间的字符。
  5. characters after 'z'. 'z'之后的字符。

What you need is to handle characters in areas 1 and 3 once shifted (since you're only performing subtractions, area 5 will never be reached). 您需要的是一旦移位就处理区域1和3中的字符(因为您仅执行减法,所以永远不会到达区域5)。

You should also use characters in your conditions instead of numerical values for readability. 为了便于阅读,还应在条件中使用字符而不是数字。 Try: 尝试:

char* s1 = "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop";
int s1s = strlen(s1);
int i = 16;
char tmp[s1s+1];
for (int j = 0; j < s1s; ++j) {
    char tmp_s = (char) ((int) s1[j]-i);
    if(tmp_s < 'A'){ /* "area 1" */
        tmp_s += 'z'-'A' + 1; /* shift between 'a' and 'z' */
    }
    else if(tmp_s < 'a' && s1[j] >= 'a'){ /* "area 3" */
        tmp_s += 'Z'-'a' + 1; /* shift between 'A' and 'Z' */
    }
    tmp[j]=tmp_s;
}
tmp[s1s]='\0';

The code may need further adaptations if you allow i to be high enough to "jump" more than one area. 如果您允许i足够高以“跳转”多个区域,则代码可能需要进一步修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM