Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 647|回复: 0

[算法学习]队列应用之凯撒加密法

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-3 00:01:06 | 显示全部楼层 |阅读模式
    1.凯撒加密(Caesar cipher)简介
         凯撒加密(Caesar cipher)是一种简单的消息编码方式:它根据字母表将消息中的每个字母移动常量位k。举个例子
    如果k等于3,则在编码后的消息中,每个字母都会向前移动3位:a会被替换为d;b会被替换成f;依此类推。字母表末尾将回卷到字母表开头。于是,w会被替换为z, x会被替换为a。 在解码消息的时候,每个字母会反方向移动同样的位数。因此,如果k等于3,下面这条编码后的消息:
    vlpsolflwb iroorzv frpsohalwb
    会被解码成:
    simplicity follows complexity

         朱丽叶斯.凯撒在他的一些机密政府通信中真正用到了这种加密。遗憾的是,凯撒加密相当容易被破解。字母的移动只有26种可能;要破解密码,只需尝试各种密钥值, 直到有一种可行即可。 使用重复密钥(repeating key)可以对这种编码技术做出改进,这时不再将每个字母移动常位数,而是利用一列密钥值将各个字母移动不同的位数。如果消息长于这列密钥
    值,可以从头再次使用这列密钥。例如,假设密钥值为:  
      
       
       
         
       

         
       
      
      3     1      7     4     2     5
    则第1个字母会移动3位,第2个字母会移动1位,依此类推,将第6个字母移动5位之后,我们会从头再次使用这列密钥。于是第7个字母会移动3位,第8个字母会移动1位。反之解码的过程类似。

    2.代码实现
    我们都知道队列的特点是FIFO(先进先出),将密钥存储在队列 中,使用了一个密钥后,将这个密钥添加到队尾,这样较长的信息可以重复使用该密钥。
    队列的java代码实现如下:
    /**
      * 链表队列的实现
      */
    public class LinkedQueue {
         private LinearNode front;
         private LinearNode rear;
         private int size;
         /**
          * 入队操作
          * @param node
          */
         public void enqueue(LinearNode node) {
             if(0 == size) {
                 front = rear = node;
             } else {
                 rear.setNext(node);
                 rear = node;            
             }
             size++;
         }
         /**
          * 出队操作
          * @return
          */
         public LinearNode dequeue() {
             if(!isEmpty()) {
                 LinearNode l = front;
                 //when the size is 1
                 if(front == rear)
                     front = rear = null;
                 else
                     front = l.getNext();
                 size--;
                 return l;
             }    else    {   
                 front = rear = null;
                 return null;
             }
         }
         /**
          * 获得队列大小
          * @return
          */
         public int size() {
             return size;
         }
         /**
          * 判断队列是否为空
          * @return
          */
         public boolean isEmpty() {
             if(0 < size)
                 return false;
             else
                 return true;
         }
         /**
          * 显示队列数据
          *
          */
         public void listNodes() {
             while(!isEmpty()) {
                 System.out.println(dequeue().getElement());            
             }
         }
         public LinearNode getFront() {
             return front;
         }
         public void setFront(LinearNode front) {
             this.front = front;
         }
         public LinearNode getRear() {
             return rear;
         }
         public void setRear(LinearNode rear) {
             this.rear = rear;
         }
         public int getSize() {
             return size;
         }
         public void setSize(int size) {
             this.size = size;
         }
    }
    front指针指向队列的第一个元素,也就是即将出队的元素;rear指针指向队尾元素,也就是刚入队的元素。如果队列为空则入队时front和rear都指向刚入队的
    元素;如果最后一个元素出队,队列为空,front和rear都为null。
    凯撒加密代码如下:
    /**
      *  凯撒加密
      */
    public class KasarEncryption {
         private LinkedQueue encKeyQueue = new LinkedQueue();
         private LinkedQueue decKeyQueue = new LinkedQueue();
         public KasarEncryption(int key[]) {
             genKey(key);
         }
         /**
          * 处理密钥
          * @param key
          */
         private void genKey(int[] key) {
             for(int i = 0 ; i < key.length ; i++) {
                 encKeyQueue.enqueue(new LinearNode<Integer>(new Integer(key)));
            decKeyQueue.enqueue(new LinearNode<Integer>(new Integer(key)));
             }
         }
         /**
          * 加密
          * @param plainText
          * @return
          */
         public String encrypt(String plainText) {
             char chars[] = plainText.toCharArray();
             for(int i = 0 ; i < chars.length ; i++) {
                 LinearNode<Integer> l = encKeyQueue.dequeue();
                 int movement = l.getElement().intValue();
                 chars += movement;
                 encKeyQueue.enqueue(l);
             }
             return new String(chars);
         }
         /**
          * 解密
          * @param encryptedText
          * @return
          */
         public String decrypt(String encryptedText) {
             char chars[] = encryptedText.toCharArray();
             for(int i = 0 ; i < chars.length ; i++) {
                 LinearNode<Integer> l = decKeyQueue.dequeue();
                 int movement = l.getElement().intValue();
                 chars -= movement;
                 decKeyQueue.enqueue(l);
             }
             return new String(chars);
         }
         public static void main(String args[]) throws InterruptedException {
             String plainText = "my name is bilei";
             int key[] = {3,5,4,1};
             KasarEncryption ke = new KasarEncryption(key);
             if(args.length > 0) {
                 plainText = "";
                 for(int i = 0 ; i < args.length ; i++) {        
                     if(i == args.length-1)
                         plainText += args;
                     else
                    plainText += args+" ";
                 }
             }
             System.out.println("明文 "+plainText);
             System.out.println("加密........");
             String encryptedText = ke.encrypt(plainText);
             System.out.println("密文 "+encryptedText);
             Thread.sleep(3000);
             System.out.println("解密........");
             System.out.println("明文 "+ke.decrypt(encryptedText));
         }   
    }
    我们要用到两个队列,一个为加密队列,另一个为解密队列,这两个队列存放相同的密钥,消息格式存储为String类型,在加密解密操作时,将其转换为char数组
    分别对数组中每一元素进行加密。
    代码测试:
    明文 darkdiable is jason;jason is darkdiable
    加密........
    密文 gfvlgnecoj$jv%nbvtr<mfwpq%mt#iesnimbeqi
    解密........
    明文 darkdiable is jason;jason is darkdiable
    因为JAVA虚拟机中的编码方式采用unicode,char类型为2字节,所以对于中文编码也能很好支持,测试如下:
    明文 凯撒加密测试
    加密........
    密文 ���寇济诚
    解密........
    明文 凯撒加密测试



      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/3/000105937.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2026-6-20 00:52 , Processed in 0.505019 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表