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

目录

1⃣️前言

des加密解密代码编写属实不易,克服很多了bug,如果想要代码的请先点赞关注一波!!des加密解密的Java版代码+GUI图形界面显示[8848钛金手机-加密通话-离开10米自动爆炸]

2⃣️加密解密思路

其实B站很多学习视频都有讲怎么加密的,我这里就不再赘述。
解密思路就是和加密稍微有点不一样,加密的时候有L,R的运算,看下面这张图的思维导图部分,解密的时候就是反过来,把R当成L,L当成R,然后密钥内容不变,密钥使用顺序相反,加密的时候就是Key1到Key16依次使用,解密就是Key16到Key1依次使用
des加密解密的Java版代码+GUI图形界面显示[8848钛金手机-加密通话-离开10米自动爆炸]

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("加密
上一篇:List


下一篇:(转)springAOP解析-2