ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

des加密解密的Java版代码+GUI图形界面显示[8848钛金手机-加密通话-离开10米自动爆炸]

2021-12-13 10:32:04  阅读:188  来源: 互联网

标签:10 13 12 加密 LinkedList int 图形界面 private new


目录

1⃣️前言

des加密解密代码编写属实不易,克服很多了bug,如果想要代码的请先点赞关注一波!!在这里插入图片描述

2⃣️加密解密思路

其实B站很多学习视频都有讲怎么加密的,我这里就不再赘述。
解密思路就是和加密稍微有点不一样,加密的时候有L,R的运算,看下面这张图的思维导图部分,解密的时候就是反过来,把R当成L,L当成R,然后密钥内容不变,密钥使用顺序相反,加密的时候就是Key1到Key16依次使用,解密就是Key16到Key1依次使用
在这里插入图片描述

3⃣️Des.java代码(加密解密的代码)

package 实验2.des加密;

import java.security.Key;
import java.util.*;

import static java.lang.Integer.toBinaryString;
import static java.lang.Integer.valueOf;

public class Des {
    /**
     * 密文
     *
     */
    private LinkedList<Integer> cipher;
    /**
     * P盒置换所用矩阵
     *
     */
    private int[] P_Box = new int[]{
            16, 7, 20, 21, 29, 12, 28, 17,
            1, 15, 23, 26, 5, 18, 31, 10,
            2, 8, 24, 14, 32, 27, 3, 9,
            19, 13, 30, 6, 22, 11, 4, 25
    };
    /**
     * S盒压缩
     * s[i][j][k]
     * 第i个二维数组
     * 第j行,第k列
     */
    private static int[][][] S_Box = new int[][][]{
            // S1
            {
                    {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
                    {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
                    {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
                    {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
            },

            //S2
            {
                    {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
                    {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
                    {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
                    {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
            },

            //S3
            {
                    {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
                    {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
                    {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
                    {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
            },

            //S4
            {
                    {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
                    {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
                    {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
                    {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
            },

            //S5
            {
                    {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
                    {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
                    {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
                    {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
            },
            //S6
            {
                    {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
                    {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
                    {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
                    {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,}
            },
            //S7
            {
                    {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
                    {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
                    {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
                    {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
            },
            //S8
            {
                    {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
                    {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
                    {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
                    {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
            },

    };
    /**
     * E 扩展置换表
     */
    private int[] extension = {
            32, 1, 2, 3, 4, 5,
            4, 5, 6, 7, 8, 9,
            8, 9, 10, 11, 12, 13,
            12, 13, 14, 15, 16, 17,
            16, 17, 18, 19, 20, 21,
            20, 21, 22, 23, 24, 25,
            24, 25, 26, 27, 28, 29,
            28, 29, 30, 31, 32, 1
    };
    /**
     * 生成密钥所用移位表
     */
    private int[] shiftBit = {
            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
    };
    /**
     * 初始置换表
     */
    private final int[] initMatrix = {
            58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
            62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
            57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
            61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
    };
    /**
     * 终止置换表
     */
    private final int[] finalMatrix = {
            40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
            38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
            36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
            34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
    };
    /**
     * 要加密的数据
     */
    private int[] data = {
            0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
            0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1,
            0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1,
            0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0
    };
    /**
     * 密钥
     */
    private int[] key = {
            0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0,
            0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1,
            1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0,
            1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1
    };
//    private int[] key = {
//            0,0,1,1, 0,0,0,1,
//            0,0,1,1, 0,0,1,0,
//            0,0,1,1, 0,0,1,1,
//            0,0,1,1, 0,1,0,0,
//            0,0,1,1, 0,1,0,1,
//            0,0,1,1, 0,1,1,0,
//            0,0,1,1, 0,1,1,1,
//            0,0,1,1, 1,0,0,0
//    };
    /**
     * key置换生成C0,D0矩阵,只有56个元素,剔除了8位校验位
     * 转换成56位矩阵
     */
    private int[] PC1 = {
            57, 49, 41, 33, 25, 17, 9,
            1, 58, 50, 42, 34, 26, 18,
            10, 2, 59, 51, 43, 35, 27,
            19, 11, 3, 60, 52, 44, 36,
            63, 55, 47, 39, 31, 23, 15,
            7, 62, 54, 46, 38, 30, 22,
            14, 6, 61, 53, 45, 37, 29,
            21, 13, 5, 28, 20, 12, 4
    };
    /**
     * PC1生成的乱序数据
     */
    private int[] res_PC1;

    /**
     * 后续生成密钥的矩阵
     * <p>
     * 转换成为48位密钥
     */
    private int[] PC2 = {
            14, 17, 11, 24, 1, 5,
            3, 28, 15, 6, 21, 10,
            23, 19, 12, 4, 26, 8,
            16, 7, 27, 20, 13, 2,
            41, 52, 31, 37, 47, 55,
            30, 40, 51, 45, 33, 48,
            44, 49, 39, 56, 34, 53,
            46, 42, 50, 36, 29, 32
    };

    /**
     * 初始置换之后的结果
     */
    private int[] permutation;
    private LinkedList<Integer> pertArray;//permutation的ArrayList形式
    private LinkedList<Integer> Ri;//Ri的表示
    private LinkedList<Integer> Li;//Li的表示
    private LinkedHashMap<Integer, LinkedList<Integer>> kMap;//存储了16个密钥
    private LinkedList<Integer> plainText;//明文

    {
        permutation = new int[64];
        pertArray = new LinkedList<>();
        Li = new LinkedList<>();//L0
        Ri = new LinkedList<>();//R0
        res_PC1 = new int[PC1.length];
        kMap = new LinkedHashMap<>();
    }

    private void arrayToArrayList() {
        for (var item : permutation) {
            pertArray.add(item);
        }
        for (int i = 0; i < pertArray.size() >> 1; i++) {//0~31,<32
            Li.add(pertArray.get(i));//Li初始化
            Ri.add(pertArray.get(i + 32));//Ri初始化
        }
    }

    public Des() {
        generateSubKey();
        InitialPermutation();
        code();
        printCipher();
        decode();
        printPlainText();

    }

    /**
     * 假定L就是64位的数据
     * @param L
     */
    public Des(LinkedList<StringBuilder> L,int[] newKey){
        generateSubKey();
        this.data=new int[64];
        this.key=newKey;
        for (int i = 0; i < L.size(); i++) {
            StringBuilder binaryString=new StringBuilder(L.get(i));
            for (int j = 0; j < binaryString.length(); j++) {
                data[i*8+j]=binaryString.charAt(j)-'0';
            }
        }
        InitialPermutation();
        code();
        printCipher();
        decode();
        printPlainText();
    }
    /**
     * 初始置换
     */
    private void InitialPermutation() {
        printKey();
        for (int i = 0; i < permutation.length; i++) {
            permutation[i] = data[initMatrix[i] - 1];//求置换后的数据
        }
        System.out.println("IP置换前");
        print(permutation,8 );
    }

    /**
     * 终止置换
     */
    private LinkedList<Integer> FinalPermutation(LinkedList<Integer> list) {
        LinkedList<Integer> res=new LinkedList<>();
        for (var item : finalMatrix)
        {
            res.addLast(list.get(item-1));
        }
        System.out.println("IP^-1后");
        print(res, 8);
        return res;
    }

    /**
     * 显示密文
     */
    public void code() {
        arrayToArrayList();//分组
        LinkedList<Integer> L,R;
        L=Li;
        R=Ri;
        for (int i = 1; i <= 16; i++) {
            LinkedList<Integer> tmp=R;
            R=xor(L, ff(R, i));//F函数处理R和第i个密钥,处理返回结果res,res和L异或
            L=tmp;
        }
        R.addAll(L);//L和R合并再次IP逆置换
        cipher = FinalPermutation(R);
    }

    /**
     * 生成16个密钥,存储在kMap中
     *
     */
    private void generateSubKey() {
        LinkedList<Integer> C0 = new LinkedList<>();
        LinkedList<Integer> D0 = new LinkedList<>();
        for (int i = 0; i < PC1.length; i++) {
            res_PC1[i] = key[PC1[i] - 1];//数字代表了第几位,所以要-1才能用下标访问
        }
        /**
         * 完成对C0,D0的初始化
         *
         *
         */
        for (int i = 0; i < 28; i++) {
            C0.add(res_PC1[i]);
            D0.add(res_PC1[i + 28]);
        }
        /**
         * 完成对密钥Ki对逐个加密,一个要生成16个密钥
         *
         */
        for (int i = 1; i <= 16; i++) {
            shiftKRound(C0, shiftBit[i - 1]);//shiftBit是从0开始,计数i是从1开始,所以要-1
            shiftKRound(D0, shiftBit[i - 1]);
            LinkedList<Integer> kth_Key = new LinkedList<>();
            LinkedList<Integer> cd = new LinkedList<>(C0);
            cd.addAll(D0);//相当于C0和D0合并了
            for (var item : PC2) {
                kth_Key.addLast(cd.get(item - 1));
            }
            kMap.put(i, kth_Key);//i存储密钥Ki
        }
    }

    /**
     * 循环左移K次,在生成密钥时使用的函数
     *
     * @param list
     * @param k
     */
    private void shiftKRound(LinkedList<Integer> list, int k) {
        for (int i = 0; i < k; i++) {
            list.add(list.poll());
        }
    }

    /**
     * F函数
     * 输入的是第i个密钥
     */
    private LinkedList<Integer> ff(LinkedList<Integer> a, int i) {
        LinkedList<Integer> list = e_transform(a);
        list = xor(list, kMap.get(i));//得到异或的结果
        list=ss(list);//list指向了被压缩之后第i数据,第i-1就是第k个S盒,k从0~7
        list=p_transform(list);
//        print(a);
        return list;
    }

    /**
     * e扩展置换,32->48
     */
    private LinkedList<Integer> e_transform(LinkedList<Integer> a) {
        LinkedList<Integer> copy = new LinkedList<>();
        for (var item : extension) {
            copy.add(a.get(item - 1));
        }
        System.out.println("E扩展之后");
        print(copy, 8);
        return copy;
    }

    /**
     * F函数中的异或XOR
     * 48 bits -> 48 bits
     */
    private LinkedList<Integer> xor(LinkedList<Integer> list, LinkedList<Integer> key) {
        LinkedList<Integer> res = new LinkedList<>();
        Iterator<Integer> it1 = list.iterator();
        Iterator<Integer> it2 = key.iterator();
        while (it1.hasNext()) {
            Integer i1 = it1.next();
            Integer i2 = it2.next();
            res.addLast(i1 ^ i2);
        }
        System.out.println("xor之后");
        print(res, 8);
        return res;
    }

    /**
     * S盒压缩处理
     *
     * @param list 是异或完了之后的数据
     * @param k    第k个S盒,0<=k<=7
     */
    private LinkedList<Integer> ss(LinkedList<Integer> list) {
        LinkedList<Integer> compress_ans = new LinkedList<>();
        for (int i = 0, k = 0; i < 48 && k < 8; i += 6, ++k) {
            Integer i1 = list.get(i), i2 = list.get(i + 1), i3 = list.get(i + 2), i4 = list.get(i + 3), i5 = list.get(i + 4), i6 = list.get(i + 5);
            /**
             * @row 一个S盒中的行
             * @col 一个S盒中的列
             *
             */
            Integer row = valueOf(i1 + "" + i6, 2);
            Integer col = valueOf(i2 + "" + i3 + "" + i4 + "" + i5, 2);
            StringBuilder s = new StringBuilder(toBinaryString(S_Box[k][row][col]));
            /**
             * 防止不足4位的情况发生,所以要把缺少的0补上
             */
            while (s.length() < 4) {
                s.insert(0, '0');
            }
            for (int it = 0; it < s.length(); it++) {
                compress_ans.addLast(s.charAt(it) - '0');
            }
        }
        System.out.println("S盒变换之后");
        print(compress_ans, 8);
        return compress_ans;
    }

    /**
     * F函数中的P置换
     */
    private LinkedList<Integer> p_transform(LinkedList<Integer> list) {
        LinkedList<Integer> res = new LinkedList<>();
        for (var item : P_Box)
        {
            res.addLast(list.get(item - 1));
        }
        System.out.println("P盒置换");
        print(res, 8);

        return res;
    }

    /**
     * 解密
     */
    public void decode() {
        for (int i = 0; i < permutation.length; i++) {
            permutation[i] = cipher.get(initMatrix[i] - 1);
        }
        pertArray = new LinkedList<>();
        Li = new LinkedList<>();//L0
        Ri = new LinkedList<>();//R0
        //不需要重新计算密钥,故不重新new一个LinkedHashMap
        arrayToArrayList();
        LinkedList<Integer> L=Ri,R=Li;
        for (int i = 16; i >= 1; i--) {
            LinkedList<Integer> tmp=L;
            L=xor(ff(L, i),R);
            R=tmp;
        }
        L.addAll(R);
        plainText=FinalPermutation(L);
    }

    private void printKey() {
        for (var item : kMap.entrySet()) {
            System.out.printf("第%2d个密钥:", item.getKey());
            System.out.print(item.getValue().toString());
            System.out.println(",密钥长度:" + item.getValue().size());
        }
    }
    public void printPlainText(){
        System.out.println("明文:\n");
        int count=0;
        for (var item : plainText)
        {
            System.out.printf("%3d",item);
            count++;
            if (count==16){
                count=0;
                System.out.println();
            }
        }
        System.out.println();
    }
    public void printCipher(){
        System.out.println("密文:\n");
        int count=0;
        for (var item : cipher)
        {
            System.out.printf("%3d",item);
            count++;
            if (count==16){
                count=0;
                System.out.println();
            }
        }
        System.out.println();
    }
    private static ArrayList<Integer> arrayToArrayList(int[] a) {
        ArrayList<Integer> res = new ArrayList<>();
        for (var item : a) {
            res.add(item);
        }
        return res;
    }
    public static void main(String[] args) {
        new Des();
    }

    public LinkedList<Integer> getCipher() {
        return cipher;
    }

    public LinkedList<Integer> getPlainText() {
        return plainText;
    }

    private void print(Collection<?> c,int col){
        int i=0,count=0;
        for (var item : c)
        {
            count++;
            System.out.print(item+" ");
            if (count==col){
                count=0;
                System.out.println();
            }
        }
        System.out.println("Query OK");
    }
    private void print(int[] a,int col){
        int i=0,count=0;
        for (var item : a)
        {
            count++;
            System.out.print(item+" ");
            if (count==col){
                count=0;
                System.out.println();
            }
        }
        System.out.println("Query OK");
    }
}

4⃣️Demo.java(图形界面代码)

package 实验2.des加密;

import javax.swing.*;
import java.awt.*;
import java.util.LinkedList;
import static java.lang.Integer.*;
import static java.awt.BorderLayout.*;

public class Demo extends JFrame {
    private JLabel inputChL,cipherL,plainTextL,keyL,rightReserve;
    private JButton lockjb,unlockjb,clearjb;
    private JTextArea inputChArea,cipherTextArea,plainTextArea;
    private JTextField keyF;
    private JPanel leftP, southP,downP;
    private Font kaishu;
    private LinkedList<Des> list;
    {
        downP=new JPanel();
        rightReserve=new JLabel("@HWG© All Right Reserved ");
        list=new LinkedList<>();
        kaishu=new Font(Font.DIALOG_INPUT  ,Font.BOLD,12);
        keyL=new JLabel("8位密钥");
        inputChL=new JLabel("请输入字符");
        cipherL=new JLabel("密文");
        plainTextL=new JLabel("明文");

        lockjb=new JButton("加密

标签:10,13,12,加密,LinkedList,int,图形界面,private,new
来源: https://blog.csdn.net/weixin_46028606/article/details/121899209

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有