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