C#实现DES加密解密算法

最近学了DES算法,用C#实现了一下,其中算法描述可以从书上或网上了解,关键的一点是加密和解密过程就一点不同,即加密过程使用K1,K2...K15,解密过程使用K15,K14...K1.此例中也可以以文本形式输出。

  界面

代码如下(控件的name见文知意):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace DES_16
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        int[] IP = {  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
                    };
        int[] IP_1 = {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,
                    };
        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
                  };
        int[] P = {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
                  };
        int[] PC_1 = {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
                     };
        int[] PC_2 = {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
                     };
        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} 
                    };
        char[,] K = new char[16,48];
        private void jiSuanK()
        {
            long miYao = Convert.ToInt64(tbMiYao.Text, 16);
            string binaryMiYao = Convert.ToString(miYao, 2).PadLeft(64, '0');
            char[] binaryMiYaoArray = binaryMiYao.ToCharArray();
            char[] miYaoPC_1 = new char[56];
            for (int i = 0; i < 56; i++)
            {
                miYaoPC_1[i] = binaryMiYaoArray[PC_1[i] - 1];
            }
            //求 C0 D0
            char[] miYaoPC_1_C0 = new char[28];
            char[] miYaoPC_1_D0 = new char[28];
            for (int i = 0; i < 27; i++)
            {
                miYaoPC_1_C0[i] = miYaoPC_1[i + 1];
            }
            miYaoPC_1_C0[27] = miYaoPC_1[0];
            for (int i = 0; i < 27; i++)
            {
                miYaoPC_1_D0[i] = miYaoPC_1[29 + i];
            }
            miYaoPC_1_D0[27] = miYaoPC_1[28];
            for (int cycle = 0; cycle < 16; cycle++)
            {
                switch (cycle)
                {
                    case 0:
                        break;
                    case 1:
                    case 8:
                    case 15:
                        char a1 = miYaoPC_1_C0[0];
                        for (int i = 0; i < 27; i++)
                        {
                            miYaoPC_1_C0[i] = miYaoPC_1_C0[i + 1];
                        }
                        miYaoPC_1_C0[27] = a1;
                        char b1 = miYaoPC_1_D0[0];
                        for (int i = 0; i < 27; i++)
                        {
                            miYaoPC_1_D0[i] = miYaoPC_1_D0[1 + i];
                        }
                        miYaoPC_1_D0[27] = b1;
                        break;
                    default:
                        char c1 = miYaoPC_1_C0[0];
                        char d1 = miYaoPC_1_C0[1];
                        for (int i = 0; i < 26; i++)
                        {
                            miYaoPC_1_C0[i] = miYaoPC_1_C0[i + 2];
                        }
                        miYaoPC_1_C0[26] = c1;
                        miYaoPC_1_C0[27] = d1;
                        char e1 = miYaoPC_1_D0[0];
                        char f1 = miYaoPC_1_D0[1];
                        for (int i = 0; i < 26; i++)
                        {
                            miYaoPC_1_D0[i] = miYaoPC_1_D0[2 + i];
                        }
                        miYaoPC_1_D0[26] = e1;
                        miYaoPC_1_D0[27] = f1;
                        break;
                }
                char[] miYaoPC_2 = new char[56];
                for (int i = 0; i < 28; i++)
                {
                    miYaoPC_2[i] = miYaoPC_1_C0[i];
                }
                for (int i = 0; i < 28; i++)
                {
                    miYaoPC_2[i + 28] = miYaoPC_1_D0[i];
                }
                char[] K1 = new char[48];
                for (int i = 0; i < 48; i++)
                {
                    K1[i] = miYaoPC_2[PC_2[i] - 1];
                }
                for (int i = 0; i < 48; i++)
                {
                    K[cycle, i] = K1[i];
                }
            }
        }
        //加密
        private void btnJiaMi_Click(object sender, EventArgs e)
        {
            jiSuanK();
            jiaJieMi(tbMingWen, tbMiWen);
            createWenBen("加密后所得密文.txt", tbMiWen);
        }
        private void btnJieMi_Click(object sender, EventArgs e)
        {
            jiSuanK();
            jiaJieMi(tbJieMiMiWen, tbJieMiMingWen);
            createWenBen("解密后所得明文.txt", tbJieMiMingWen);
        }
        private void jiaJieMi(TextBox tb, TextBox tb2)
        {
            long mingWen = Convert.ToInt64(tb.Text, 16);
            string binaryMingWen = Convert.ToString(mingWen, 2).PadLeft(64, '0');
            char[] binaryMingWenArray = binaryMingWen.ToCharArray();
            //获得L0 R0
            char[] mingWen_IP = new char[64];
            for (int i = 0; i < 64; i++)
            {
                mingWen_IP[i] = binaryMingWenArray[IP[i] - 1];
            }
            char[] L0 = new char[32];
            char[] R0 = new char[32];
            for (int i = 0; i < 32; i++)
            {
                L0[i] = mingWen_IP[i];
            }
            for (int i = 0; i < 32; i++)
            {
                R0[i] = mingWen_IP[32 + i];
            }
            //循环十六次加密
            for (int cycle = 0; cycle < 16; cycle++)
            {
                char[] R0_E = new char[48];
                for (int i = 0; i < 48; i++)
                {
                    R0_E[i] = R0[E[i] - 1];
                }
                char[] A = new char[48];
                for (int i = 0; i < 48; i++)
                {
                    if(tb.Equals(tbMingWen))
                        A[i] = R0_E[i].Equals(K[cycle, i]) ? '0' : '1';
                    else
                        A[i] = R0_E[i].Equals(K[15-cycle, i]) ? '0' : '1';
                }
                int[] binaryA = new int[48];
                for (int i = 0; i < 48; i++)
                {
                    binaryA[i] = Convert.ToInt32(A[i].ToString());
                }
                int s1 = S1[binaryA[0] * 2 + binaryA[5], binaryA[1] * 8 + binaryA[2] * 4 + binaryA[3] * 2 + binaryA[4]];
                int s2 = S2[binaryA[6] * 2 + binaryA[11], binaryA[7] * 8 + binaryA[8] * 4 + binaryA[9] * 2 + binaryA[10]];
                int s3 = S3[binaryA[12] * 2 + binaryA[17], binaryA[13] * 8 + binaryA[14] * 4 + binaryA[15] * 2 + binaryA[16]];
                int s4 = S4[binaryA[18] * 2 + binaryA[23], binaryA[19] * 8 + binaryA[20] * 4 + binaryA[21] * 2 + binaryA[22]];
                int s5 = S5[binaryA[24] * 2 + binaryA[29], binaryA[25] * 8 + binaryA[26] * 4 + binaryA[27] * 2 + binaryA[28]];
                int s6 = S6[binaryA[30] * 2 + binaryA[35], binaryA[31] * 8 + binaryA[32] * 4 + binaryA[33] * 2 + binaryA[34]];
                int s7 = S7[binaryA[36] * 2 + binaryA[41], binaryA[37] * 8 + binaryA[38] * 4 + binaryA[39] * 2 + binaryA[40]];
                int s8 = S8[binaryA[42] * 2 + binaryA[47], binaryA[43] * 8 + binaryA[44] * 4 + binaryA[45] * 2 + binaryA[46]];
                int b = (s1 << 28) + (s2 << 24) + (s3 << 20) + (s4 << 16) + (s5 << 12) + (s6 << 8) + (s7 << 4) + s8;
                string B = Convert.ToString(b, 2).PadLeft(32, '0');
                char[] binaryB = B.ToCharArray();
                char[] P_B = new char[32];
                for (int i = 0; i < 32; i++)
                {
                    P_B[i] = binaryB[P[i] - 1];
                }
                char[] R1 = new char[32];
                for (int i = 0; i < 32; i++)
                {
                    R1[i] = P_B[i].Equals(L0[i]) ? '0' : '1';
                }
                L0 = R0;
                R0 = R1;
            }
            char[] lastLR = new char[64];
            for (int i = 0; i < 32; i++)
            {
                lastLR[i] = R0[i];
            }
            for (int i = 0; i < 32; i++)
            {
                lastLR[32 + i] = L0[i];
            }
            char[] lastLR_IP_1 = new char[64];
            for (int i = 0; i < 64; i++)
            {
                lastLR_IP_1[i] = lastLR[IP_1[i] - 1];
            }
            long[] binaryMiWen = new long[64];
            for (int i = 0; i < 64; i++)
            {
                binaryMiWen[i] = Convert.ToInt64(lastLR_IP_1[i].ToString());
            }
            long miWen = 0;
            for (int i = 0; i < 64; i++)
            {
                miWen += (binaryMiWen[i] << (63 - i));
            }
            tb2.Text = Convert.ToString(miWen, 16);
        }
        private void createWenBen(string str, TextBox tb)
        {
            string text1 = tb.Text;
            string path2 = str;
            FileStream fileStream = null;
            StreamWriter streamWriter = null;
            fileStream = new FileStream(path2, FileMode.Create, FileAccess.Write);
            streamWriter = new StreamWriter(fileStream, System.Text.Encoding.Default);
            streamWriter.WriteLine(text1);
            streamWriter.Flush();
            streamWriter.Close();
            fileStream.Close();  
        }
    }
} 

具体c#代码:http://download.csdn.net/source/1418013

---
可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
原文地址:https://www.cnblogs.com/null00/p/2065095.html