最近学了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