c - 我的凯撒密码版本有什么问题?参数组2

标签 c cs50 caesar-cipher

凯撒密码使用用户定义的 key 和文本来加密文本。

在密码学中,凯撒密码,也称为凯撒密码、移位密码、凯撒码或凯撒移位,是最简单且最广为人知的加密技术之一。它是一种替换密码,其中明文中的每个字母都被字母表中固定数量位置的字母替换。例如,左移 3,D 将被 A 替换,E 将变为 B,依此类推。该方法以凯撒大帝的名字命名,他在私有(private)信件中使用了该方法

#include <stdio.h>
#include <cs50.h>
#include <ctype.h>


int main ( int argc , string argv[] )
{    
  int key,save;
  string s ;

  key = atoi(argv[1]);    
  s = GetString();

  if (  argc != 2 )
  {
    printf("prgram is yelling at you !!");
    return 1 ;
  }

  for ( int i = 0  ; s[i]!='\0' ; ++i)  // manipulation without storing character
  {
    if ( isalpha( s[i]) )           // checks whether input is in character set or not
    {
      if ( islower ( s[i] ) )       // FOR LOWER CASES
      {
        save = key % 24 ;
        s[i] = s[i] + save ;

        if ( s[i] > 'z' )
          s[i] = 'a' + ( s[i] - 'z' -1 );
      }

      if ( isupper ( s[i] ) )        // FOR UPPER CASES
      {
        save = key  % 24 ;
        s[i] =  s[i] + save ;

        if ( s[i] > 'Z' )
          s[i] = 'A' + ( s[i] - 'Z' -1 );
      }
    }

    printf ( "%c" , s[i] );
  }

  return 0 ;
}

事实:

:) caesar.c exists 
:) caesar.c compiles
:( encrypts "a" as "b" using 1 a s key
   \ expected output, but not "b" 
:( encrypts "barfoo" as "yxocll" using 23 as key
   \ expected output, but not "yxc"
:( encrypts "BARFOO" as "EDUIRR" using 3 as key
   \ expected output, but not "EDUIRR"
   :( encrypts "BaRFoo" as "FeVJss" using 4 as key
      \ expected output, but not "FeVJss"
   :( encrypts "barfoo" as "onesbb" using 65 as key
        \ expected output, but not "srw"
   :( encrypts "world, say hello!" as "iadxp, emk tqxxa!" using   12 as key
       \ expected output, but not "adxp, em tqxxa!"

   :( handles lack of argv[1]
        \ expected output, not standard error of \      "/opt/sandbox50/bin/run.sh: line 31: 189..."

最佳答案

问题是您使用 char 类型来存储对于该类型来说太大的中间计算,而不是更大的类型。这个计算:

s[i] = s[i] + save ;

由于整数提升,加法将在 int 类型中完成,但随后它将被分配回 char 类型,结果将由实现定义。它可能会环绕并给出无效值。

要解决此问题,请使用 int 来存储结果

int temp = s[i] + save;
if ( temp > 'z' )
    temp = 'a' + ( temp - 'z' -1 );   
s[i] = temp;

关于c - 我的凯撒密码版本有什么问题?参数组2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38181603/

相关文章:

c - 如何清除 scanf 读取的内容?

c - 如何获取 3D 矩阵中数组的大小?

c - malloc结构C

c - 我在 Windows 10 上找不到/rootfs

c - 在 Luhn's Alg 上制作了一个脚本。无法清楚地理解如何为修改后的脚本创建和调用函数

c - scanf(...) 和 fgets(...) 问题

c - 为什么在 C99 中不允许隐式声明 get()?

java - 凯撒密码(频率列表)

c# - 凯撒密码移位(使用字母数组)

c - 如何通过精确大小计算来存储 AES_encrypt 大小密码?