再谈凯撒密码

标签: , ,

偶尔会在博客写些文章来抨击网上那些乱七八糟的代码,今天却被念初一的小朋友华丽的鄙视了一番。

文章链接:http://true-false.eu5.org/?p=13

关于恺撒密码的算法及实现,网上一搜一大堆,但有些代码是有问题的。比如这个:https://demon.tw/programming/c-caesar.html。当偏移量为负时,我们很欣喜地看到了乱码。

我写的代码固然不正确,他写的就正确了吗?

/* 恺撒密码的加密 */
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define _abs(x) (x>=0 ? x : -(x))
char *caesar (const char *, const int);
inline char caesar_ch (const char, const int);

char *caesar (const char *s, const int n)
{
        char *cs = (char *)malloc((strlen(s)+1) * sizeof(char));
        int i = 0;
        while (s[i]) {
                cs[i] = caesar_ch(s[i], n);
                i++;
        }
        cs[i] = '\0';
        return cs;
}
inline char caesar_ch (const char c, const int n)
{
        char datum = 'a';
        if (!isalpha(c)) 
                return c;
        if (isupper(c)) 
                datum = 'A';
        c -= datum; /* l-value specifies const object */
        return datum + _abs((c + n) % 26);
}

很遗憾,他的代码连编译都无法通过,错误已经用红色高亮了,试图修改被定义为const char的c变量。当然,这应该只是笔误,编译器能发现的问题基本上都不是问题。

最大的问题在于他的代码也存在逻辑错误,当偏移量为负,假设是-3吧,字母A对应的应该是X,而按照他的代码,字母A对应的是D。他认识到对于带负数的取模运算是有争议的,却错误的使用绝对值完事。

看似简单的算法,要正确实现并不容易,至于怎样写出正确的凯撒密码算法,还是留给读者自己思考吧。

最后想说的是,现在的小孩子太逆天了,我初一的时候还在玩GameBoy和口袋妖怪。

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. 全角空格?
  2. 改变IE查看源文件默认程序的方法
  3. FireFox插件User Agent Switcher
  4. RasEnumConnections函数返回632错误
  5. 在64位系统中使用CAPICOM

5 条评论 发表在“再谈凯撒密码”上

  1. chrt说道:

    感谢指出,已更正:http://true-false.eu5.org/?p=13

  2. […] 2012年4月6日更正:之前的代码有很明显的错误。感谢Demon的指出。真正解决了负数问题和const的新版代码: […]

  3. m208说道:

    初一写C(还是C++?对C没有了解)逆天了啊!
    同初一路过……

  4. mlweixiao说道:

    java版
    import java.util.Scanner;
    public class Caeser {
    private String source;
    private String encode;
    private String discode;
    public static String encode(String s){
    StringBuffer sb=new StringBuffer();
    for (int i=0;i<s.length();i++){
    char nc=s.charAt(i);
    int temp=(int)nc;
    nc=(char)(97+(temp-97+3)%26);
    sb.append(nc);
    }
    s=sb.toString();
    return s;
    }
    public static String discode(String s){
    StringBuffer sb=new StringBuffer();
    for (int i=0;i<s.length();i++){
    char nc=s.charAt(i);
    int temp=(int)nc;
    nc=(char)(97+(temp-97-3)%26);
    sb.append(nc);
    }
    s=sb.toString();
    return s;
    }
    public static void main(String[] args) {
    Caeser c=new Caeser();
    Scanner cin=new Scanner(System.in);
    c.source=cin.next();
    c.encode=encode(c.source);
    c.discode=discode(c.encode);
    System.out.println("encode:"+c.encode);
    System.out.println("discode:"+c.discode);
    System.exit(0);
    }
    }

留下回复