凯撒加密的最简单的理解与实现(Java版)

凯撒加密

前言

这是我的第一篇博客希望以后多多关注。
这篇文章起源于我在人工智能导论上的一次摸鱼◔ ‸◔,当时老师一节课都在脱离课本介绍,讲什么网络安全之类的问题,后面还举例子了一些加密方法巴拉巴拉,然后就开始介绍起来了凯撒加密,让大家找规律,我觉得还蛮有意思,而且比较简单,这个东西,然后在可以手动完成加密的基础上,想要体现一下俺2年算法水平,然后就尝试的实现了一下(。◕‿◕。)。

这个是当时的题目的PPT,老师让我猜一下如果密钥是DOCUMENT的话,这个密文是啥(揉眼睛 ( ‘-ωก̀ )。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JfEbUIAd-1663642472969)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa35ff9227e248c586de331437daa361~tplv-k3u1fbpfcp-watermark.image?)]

第一次看这个PPT的时候,让猜凯撒加密的原理其实,一看有点难的亚子(•ิ_•ิ),但就在一瞬间突然明白辽,还是很简单的(..•˘_˘•..)。

我来介绍一下原理吧๑乛◡乛๑:

首先第一步是确定密钥的字母顺序,按照字母表来排序,所以A上面是1,然后以此类推R上面就是6了。

然后就是把原文从左往右,从上到下,在密钥下面写下去,然后就会得到这个ppt左部分这个不完整的矩阵了。再按照密钥的字母顺序从上到下来读取,就可以获得密文了,是不是很简单呀,这个手动算凯撒加密,于是我就想要使用程序做出来,由于最近再学java,于是我就要来展示一下我的java水平了。于是一个小时过后,我就写出来了我的代码(没错我写了一个小时,一部分是Java的API还不是很熟,另一个方面是,这个算法确实好几个恶心的地方QWQ)。

具体代码:

import java.util.*;

public class Main
{
    
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        
        System.out.println("请输入秘钥:");
        ArrayList<Character> key_arraylist = new ArrayList<>();
        String key = in.nextLine();
// <1.1>
        int len_key = key.length();
        // 把密钥中的字母提取出来,然后放入列表中进行排序
        for (int i = 0; i < len_key; ++ i)
        {
            key_arraylist.add(key.charAt(i));
        }
        key_arraylist.sort(new Comparator<Character>(){ 
        // 对密钥字母排序
            @Override
            public int compare(Character o1, Character o2){
                int num = 0;
                if (o1 > o2) num = 1;
                else if (o1 == o2) num = 0;
                else num = -1;
                return num;
            }
        });
        // 构建哈希表 根据列表中的顺序 来对每个字母构建映射
        HashMap<Character, Character> map = new HashMap<>();
        for (int i = 0; i < len_key; ++ i)
        {
            map.put(key_arraylist.get(i), (char)(i + '0'));    
            // System.out.println(key_arraylist.get(i) + " " + (char)(i + '0'));
            
        }
  // </1.1>    
        // System.out.println(key_arraylist);
        System.out.println("请输入明文:");
        String [] tmp_text = in.nextLine().split(" ");
        
        String text = "";
        for (int i = 0; i < tmp_text.length; ++ i)
        {
            text += tmp_text[i];
        }
        
        // System.out.println(text + " " + text.length());
        int row = (int)Math.ceil((double)text.length() / (double)len_key);  
        int col = len_key;
        char [][] matrix = new char [row + 100][col + 100];
        int cnt = 0;
        
        // System.out.println(row);
   // <2.1>
        for (int i = 1; i <= row; ++ i)
        {
            for (int j = 0; j < col; ++ j)
            {
                
                if (cnt >= text.length()) matrix[i][j] = '*';
                else matrix[i][j] = text.charAt(cnt);
                cnt ++;
            }
        }
   // </2.1>
        cnt = 0;
        for(int i = 0; i < key.length(); ++ i)
		{
			matrix[0][cnt ++] = map.get(key.charAt(i));
	
		}	
        // 测试代码 
        // for (int i = 0; i <= row; ++ i)
        // {
        //     for (int j = 0; j < col; ++ j)
        //     {
        //         System.out.printf("%c", matrix[i][j]);
            
        //     }
        //     System.out.println();
        // }
    // <3.1>
        // 按照第一行构架哈希表
        TreeMap<Character, String> treeMap = new TreeMap<>();
        for (int i = 0; i < col; ++ i)
        {
            String tmp = "";
            for (int j = 1; j <= row; ++ j)
            {
                tmp += matrix[j][i];
            }
            // System.out.println(tmp);
            treeMap.put(matrix[0][i], tmp);
        }
        // System.out.print(treeMap.keySet());
        String res = "";
        for (Character i : treeMap.keySet()){
            res += treeMap.get(i);
        }
        System.out.println("加密结果:");
        for (int i = 0; i < res.length(); ++ i){
            char t = res.charAt(i);
            if (t != '*') System.out.print(t);
        }
   // </3.1>
    }
}

最后我再测试一组老师的作业,完美通过((٩(//̀Д/́/)۶))。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xBZMJliz-1663642472971)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/56f70fafe5b24df9b96500c16c4cf293~tplv-k3u1fbpfcp-watermark.image?)]

这个算法的几个难点分别为:٩͡[๏̯͡๏]
1.怎么确定那几个字母的顺序,并标注出来;

1.1 我采取的是哈希表解决,先对字母进行排序,然后根据排序结果,按顺序给每个字母加上一个映射,字母映射数字的形式解决,这样每个字母和自己的字母顺序就构成了一个映射。
如上面代码<1.1></1.1>


2.对于这个不完整的矩阵,怎么填充;

2.1 这里我采取的是,对于最后一行空着的部分,我使用一个非26字母的字符来填充,我用的是"*",这样就可以把这个矩阵填充为一个完整的矩阵了。
如上面代码<2.1></2.1>

3.最后矩阵怎么一行行的拿出来,因为不是顺序存储嘛;

3.1 我采取的方案是,在矩阵中第一行空出来,把整个矩阵都往下平移一个单位,然后把密钥各个字母对应的值,放到矩阵的第一排,然后再按照每一列的顺序,把每一列的第一个字符,当做哈希表的键,然后剩下的合并为字符串,作为哈希表的值,然后进行一波排序,最后按照哈希表,正常输出就可以了,对了记得判断一下输出的是否是"*"如果是的话,就过滤掉。如上面代码<3.1></3.1>

第一次写博客,我在51CTO掘金,上面都有相关的技术解答文章,名字都是一样的,希望大家可以关注下,为我指出错误,讨论学习,一起向着架构师前进吧。o(>ω<)o
如果觉得有帮助,来个一键三连吧(这个真的对我很重要o(>ω<)o
这是我的github改算法的代码仓库,希望为开源共同成长奉献一份力量(ง •̀_•́)ง (*•̀ㅂ•́)و:https://github.com/JIKELIHUA/Chinese-Algorithm-of-University-Software-Engineering-Course.git

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值