【Java】DES加密解密算法Java实现(仅8位明文和8位密钥)

import java.util.Scanner;

public class Exp1 {
    public static void main(String[] args) {
        char[] plainText = new char[128];
        plainText = inputPlaintext();
        System.out.println("输入明文进行二进制转换结果:");
        System.out.println(plainText);


        char[] key = new char[8];
        key = inputKey();
        System.out.println("输入密钥进行二进制转换结果:");
        System.out.println(key);

        //ip置换表
        int[] ipTable = {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
        };
        char[] ip_plainText = new char[64];
        char[] l0 = new char[32];
        char[] r0 = new char[32];
        ip_plainText = initialPermutation(ipTable, plainText, l0, r0);  //IP置换,获得l0,r0
        System.out.println("明文进行IP转换结果:");
        System.out.println(ip_plainText);
        System.out.printf("获取L0:");
        System.out.println(l0);
        System.out.printf("获取R0:");
        System.out.println(r0);

        //pc1置换表
        int[] pcTable1 = {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};

        char[] pc_Key = new char[56];
        char[] c0 = new char[28];
        char[] d0 = new char[28];
        pc_Key = initialPermutation1(pcTable1, key, c0, d0);
        System.out.println("密钥进行PC1转换结果:");
        System.out.println(pc_Key);
        System.out.printf("获取C0:");
        System.out.println(c0);
        System.out.printf("获取D0:");
        System.out.println(d0);

        //pc2置换表
        int[] pcTable2 = {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};
        char[][] k16 = new char[17][48];  //0不用
        moveCD(k16, c0, d0, pcTable2);

        char[] cipertext = new char[64];
        cipertext = functionRound(l0, r0, k16);
        System.out.print("加密密文:");
        transToascii(cipertext);

        char[] cipertext_left = new char[32];
        char[] cipertext_right = new char[32];
        //对密文进行ip置换,获得l0,r0
        initialPermutation(ipTable, cipertext, cipertext_left, cipertext_right);

        char[][] reverse_k16 = new char[17][48];
        for (int i = 1; i < 17; i++) {
            reverse_k16[i] = k16[17 - i];
        }
        char[] decipertext = new char[64];
        decipertext = functionRound(cipertext_left, cipertext_right, reverse_k16);
        System.out.print("解密密文:");
        transToascii(decipertext);

    }

    //输入明文处理
    public static char[] inputPlaintext() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要加密的明文");
        //输入要加密的明文
        String pT = sc.nextLine();
        while (true) {
            while (true) {
                if (pT.length() != 8) {
                    //判断输入长度是否正确
                    System.out.println("输入明文的长度不是八位,请重新输入");
                    pT = sc.nextLine();
                } else
                    break;
            }

            int flag = 0;
            for (int i = 0; i < 8; i++) {
                char c = pT.charAt(i);
                //判断是否能转成ascii码
                if (c > 128 || c < 0) {
                    System.out.println("输入内容不合法,请重新输入");
                    pT = sc.nextLine();
                    break;
                }
                flag++;
            }
            if (flag == 8) {
                System.out.println("输入明文合法");
                break;
            }
        }

        char[] plainText = new char[8];
        char[] hex_PT = new char[64];
        for (int i = 0; i < 8; i++) {
            plainText[i] = pT.charAt(i);
            //将每个字符转换为2进制
            String hexPlainText = Integer.toBinaryString(plainText[i]);
            for (int j = 8 * i + 7; j >= 8 * i; ) {
                for (int k = hexPlainText.length() - 1; k >= 0; k--) {
                    //将转换后的2进制赋值给字符数组
                    hex_PT[j] = hexPlainText.charAt(k);
                    j--;
                }
                //当2进制不足八位时,用0补齐位数
                while (j >= 8 * i) {
                    hex_PT[j] = '0';
                    j--;
                }
            }
        }
        return hex_PT;
    }

    //输入密钥处理
    public static char[] inputKey() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入密钥");
        //输入密钥
        String k = sc.nextLine();
        while (true) {
            while (true) {
                if (k.length() != 8) {
                    //判断输入长度是否正确
                    System.out.println("输入密钥的长度不是八位,请重新输入");
                    k = sc.nextLine();
                } else
                    break;
            }

            int flag = 0;
            for (int i = 0; i < 8; i++) {
                char c = k.charAt(i);
                //判断是否能转成ascii码
                if (c > 128 || c < 0) {
                    System.out.println("输入内容不合法,请重新输入");
                    k = sc.nextLine();
                    break;
                }
                flag++;
            }
            if (flag == 8) {
                System.out.println("输入密钥合法");
                break;
            }
        }

        char[] key = new char[8];
        char[] hex_K = new char[64];
        for (int i = 0; i < 8; i++) {
            key[i] = k.charAt(i);
            //将每个字符转换为2进制
            String hexKey = Integer.toBinaryString(key[i]);
            for (int j = 8 * i + 7; j >= 8 * i; ) {
                for (int n = hexKey.length() - 1; n >= 0; n--) {
                    //将转换后的2进制赋值给字符数组
                    hex_K[j] = hexKey.charAt(n);
                    j--;
                }
                //当2进制不足八位时,用0补齐位数
                while (j >= 8 * i) {
                    hex_K[j] = '0';
                    j--;
                }
            }
        }
        return hex_K;
    }

    //ip置换函数
    public static char[] initialPermutation(int[] ip_Table, char[] plainText, char[] l0, char[] r0) {
        char[] p_Ip = new char[64];
        for (int i = 0; i < 64; i++) {
            //将ip表中位置作为坐标进行置换
            p_Ip[i] = plainText[ip_Table[i] - 1];
        }
        for (int i = 0; i < 32; i++) {
            l0[i] = p_Ip[i];
        }
        for (int i = 32; i < 64; i++) {
            r0[i - 32] = p_Ip[i];
        }
        return p_Ip;
    }

    //PC1置换函数
    public static char[] initialPermutation1(int[] pc_Table1, char[] key, char[] c0, char[] d0) {
        char[] k_Pc = new char[56];
        for (int i = 0; i < 56; i++) {
            //将ip表中位置作为坐标进行置换
            k_Pc[i] = key[pc_Table1[i] - 1];
        }
        for (int i = 0; i < 28; i++) {
            c0[i] = k_Pc[i];
        }
        for (int i = 28; i < 56; i++) {
            d0[i - 28] = k_Pc[i];
        }
        return k_Pc;
    }

    //移动cd并进行pc置换获得子k
    public static void moveCD(char[][] k16, char[] C0, char[] D0, int[] pc_Table2) {
        char[] temp_k = new char[56];
        int i = 0;
        while (i < 16) {
            i++;
            //当第1、2、9、16轮时,只位移一位
            if (i == 1 || i == 2 || i == 9 || i == 16) {
                char temp_cfirst = C0[0];
                System.arraycopy(C0, 1, C0, 0, 27);
                C0[27] = temp_cfirst;

                char temp_dfirst = D0[0];
                System.arraycopy(D0, 1, D0, 0, 27);
                D0[27] = temp_dfirst;

                //将移位后的c,d复制到暂时的k中
                System.arraycopy(C0, 0, temp_k, 0, 28);
                System.arraycopy(D0, 0, temp_k, 28, 28);
                for (int n = 0; n < 48; n++) {
                    k16[i][n] = temp_k[pc_Table2[n] - 1];
                }
            } else {
                char temp_cfirst = C0[0];
                char temp_csecond = C0[1];
                System.arraycopy(C0, 2, C0, 0, 26);
                C0[26] = temp_cfirst;
                C0[27] = temp_csecond;

                char temp_dfirst = D0[0];
                char temp_dsecond = D0[1];
                System.arraycopy(D0, 2, D0, 0, 26);
                D0[26] = temp_dfirst;
                D0[27] = temp_dsecond;

                //将移位后的c,d复制到暂时的k中
                System.arraycopy(C0, 0, temp_k, 0, 28);
                System.arraycopy(D0, 0, temp_k, 28, 28);

                for (int n = 0; n < 48; n++) {
                    k16[i][n] = temp_k[pc_Table2[n] - 1];
                }
            }
        }
    }
    //进行十六轮计算
    public static char[] functionRound(char[] l0, char[] r0, char[][] k16) {
        //位选择函数E
        int[] e = {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};
        //S盒
        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}};
        int[][] 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}};
        int[][] 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}};
        int[][] 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}};
        int[][] 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}};
        int[][] 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}};
        int[][] 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}};
        int[][] 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}};

        int i = 0; //循环16次
        char[] feorresult = new char[48];
        while (i <= 15) {
            char[] temp_r = new char[48];
            i++;
            for (int n = 0; n < 48; n++) {
                temp_r[n] = r0[e[n] - 1];
            }

            //r部分和k进行异或操作
            for (int n = 0; n < 48; n++) {
                if (temp_r[n] == k16[i][n])
                    feorresult[n] = '0';
                else
                    feorresult[n] = '1';
            }
            int[] sresult = new int[8];  //存储经过s盒获得的十进制结果
            int[] hang = new int[8];   //存储八个盒子的行数
            int[] lie = new int[8];     //存储八个盒子的列数
            for (int n = 0; n < 48; n = n + 6) {
                int one_hang = 0;
                int one_lie = 0;
                if (feorresult[n] == '1')
                    one_hang = one_hang + 2;
                if (feorresult[n + 5] == '1')
                    one_hang = one_hang + 1;

                if (feorresult[n + 1] == '1')
                    one_lie = one_lie + 8;
                if (feorresult[n + 2] == '1')
                    one_lie = one_lie + 4;
                if (feorresult[n + 3] == '1')
                    one_lie = one_lie + 2;
                if (feorresult[n + 4] == '1')
                    one_lie = one_lie + 1;
                hang[n / 6] = one_hang;
                lie[n / 6] = one_lie;
            }

            sresult[0] = s1[hang[0]][lie[0]];
            sresult[1] = s2[hang[1]][lie[1]];
            sresult[2] = s3[hang[2]][lie[2]];
            sresult[3] = s4[hang[3]][lie[3]];
            sresult[4] = s5[hang[4]][lie[4]];
            sresult[5] = s6[hang[5]][lie[5]];
            sresult[6] = s7[hang[6]][lie[6]];
            sresult[7] = s8[hang[7]][lie[7]];

            char[] sresult_tobinary = new char[32];
            for (int n = 0; n < 8; n++) {
                String binary_result = Integer.toBinaryString(sresult[n]);
                for (int j = n * 4 + 3; j >= n * 4; ) {
                    for (int f = binary_result.length() - 1; f >= 0; f--) {
                        sresult_tobinary[j] = binary_result.charAt(f);
                        j--;
                    }
                    while (j >= 4 * n) {
                        sresult_tobinary[j] = '0';
                        j--;
                    }
                }
            }

            int[] p_Table = {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};
            char[] p_Result = new char[32];
            char[] round_Result = new char[32];
            for (int n = 0; n < 32; n++) {
                //进行p置换
                p_Result[n] = sresult_tobinary[p_Table[n] - 1];
                if (p_Result[n] == l0[n])
                    round_Result[n] = '0';
                else
                    round_Result[n] = '1';
            }
            //交换结果进行下一轮计算
            l0 = r0;
            r0 = round_Result;

        }

        char[] mergeRL = new char[64];
        System.arraycopy(r0, 0, mergeRL, 0, 32);
        System.arraycopy(l0, 0, mergeRL, 32, 32);

        int[] ip_1Table = {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};
        char[] cipertext = new char[64];
        for (int n = 0; n < 64; n++) {
            cipertext[n] = mergeRL[ip_1Table[n] - 1];
        }
        return cipertext;
    }

    //将结果转换为ascii码
    public static void transToascii(char[] text) {
        char[][] plainText = new char[8][8];
        char[] finalText = new char[8];
        int[] temp_Integer = new int[8];
        for (int i = 0; i < 8; i++) {
            System.arraycopy(text, i * 8, plainText[i], 0, 8);
            if (plainText[i][0] == '1')
                temp_Integer[i] = temp_Integer[i] + 128;
            if (plainText[i][1] == '1')
                temp_Integer[i] = temp_Integer[i] + 64;
            if (plainText[i][2] == '1')
                temp_Integer[i] = temp_Integer[i] + 32;
            if (plainText[i][3] == '1')
                temp_Integer[i] = temp_Integer[i] + 16;
            if (plainText[i][4] == '1')
                temp_Integer[i] = temp_Integer[i] + 8;
            if (plainText[i][5] == '1')
                temp_Integer[i] = temp_Integer[i] + 4;
            if (plainText[i][6] == '1')
                temp_Integer[i] = temp_Integer[i] + 2;
            if (plainText[i][7] == '1')
                temp_Integer[i] = temp_Integer[i] + 1;
        }
        for (int i = 0; i < 8; i++) {
            finalText[i] = (char) temp_Integer[i];
        }
        System.out.println(finalText);
    }
}



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Visual Studio .NET VB编程语言 MD5(DES) 8位密钥加密或解密文件function源代码 压缩包 : MD5 skey8位加密(文件).zip 列表 MD5 skey8位加密(文件)/ MD5 skey8位加密(文件)/bin/ MD5 skey8位加密(文件)/Form1.Designer.vb MD5 skey8位加密(文件)/Form1.resx MD5 skey8位加密(文件)/Form1.vb MD5 skey8位加密(文件)/MD5 skey8位加密(文件).vbproj MD5 skey8位加密(文件)/MD5 skey8位加密(文件).vbproj.user MD5 skey8位加密(文件)/My Project/ MD5 skey8位加密(文件)/My Project/Application.Designer.vb MD5 skey8位加密(文件)/My Project/Application.myapp MD5 skey8位加密(文件)/My Project/AssemblyInfo.vb MD5 skey8位加密(文件)/My Project/Resources.Designer.vb MD5 skey8位加密(文件)/My Project/Resources.resx MD5 skey8位加密(文件)/My Project/Settings.Designer.vb MD5 skey8位加密(文件)/My Project/Settings.settings MD5 skey8位加密(文件)/obj/ MD5 skey8位加密(文件)/obj/Debug/ MD5 skey8位加密(文件)/obj/Debug/CoreCompileInputs.cache MD5 skey8位加密(文件)/obj/Debug/DesignTimeResolveAssemblyReferences.cache MD5 skey8位加密(文件)/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).exe MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).pdb MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).vbproj.FileListAbsolute.txt MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).vbproj.GenerateResource.Cache MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).vbprojResolveAssemblyReference.cache MD5 skey8位加密(文件)/obj/Debug/MD5 skey8位加密(文件).xml MD5 skey8位加密(文件)/obj/Debug/TempPE/ MD5 skey8位加密(文件)/obj/Debug/TempPE/My Project.Resources.Designer.vb.dll MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.exe MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.Form1.resources MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.pdb MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.Resources.resources MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.vbproj.FileListAbsolute.txt MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.vbproj.GenerateResource.Cache MD5 skey8位加密(文件)/obj/Debug/WindowsApplication1.xml MD5 skey8位加密(文件)/obj/Release/ MD5 skey8位加密(文件).sln MD5 skey8位加密(文件).v11.suo
以下是Java代码实现DES加解密算法,包括密钥明文、密文和用户输入: ```java import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Scanner; public class DesEncryptionExample { public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); // 生成DES密钥 KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); // 显示密钥明文 byte[] keyBytes = secretKey.getEncoded(); String keyPlainText = new String(keyBytes, StandardCharsets.UTF_8); System.out.println("密钥明文:" + keyPlainText); // 加密用户输入 System.out.print("请输入要加密的内容:"); String plainText = scanner.nextLine(); byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] cipherBytes = cipher.doFinal(plainBytes); // 显示密文 String cipherText = Base64.getEncoder().encodeToString(cipherBytes); System.out.println("密文:" + cipherText); // 解密密文 cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decryptedBytes = cipher.doFinal(cipherBytes); // 显示解密后的明文 String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8); System.out.println("解密后的明文:" + decryptedText); } } ``` 在运行程序时,用户可以输入要加密的内容,程序会随机生成一个DES密钥并使用该密钥对用户输入进行加密,然后显示密钥明文和密文,并最终将密文解密并显示出解密后的明文

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值