最近要用到字符串的加密和解密,在网上得到一些代码,做了修改,让其可以加密和解密汉字(使用Unicode编码)
加密和解密的类如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace Gedee.Common.BLL
{
enum TDesMode { dmEncry, dmDecry };
class EncodeUnEncode
{
#region 静态变量
static readonly byte[] BitIP =
{
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,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6
};
static readonly byte[] BitCP =
{
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,
32, 0, 40, 8, 48, 16, 56, 24
};
static readonly int[] BitExp =
{
31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9,10,
11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,
21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0
};
static readonly byte[] BitPM =
{
15, 6,19,20,28,11,27,16, 0,14,22,25, 4,17,30, 9,
1, 7,23,13,31,26, 2, 8,18,12,29, 5,21,10, 3,24
};
static readonly byte[,] sBox =
{
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
}
};
static readonly byte[] BitPMC1 =
{
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};
static readonly byte[] BitPMC2 =
{
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31
};
#endregion
byte[][] SubKey;
public EncodeUnEncode()
{
SubKey = new byte[16][];
for (int i = 0; i < SubKey.Length; i++)
{
SubKey[i] = new byte[6];
}
}
#region 私有方法
void initPermutation(byte[] inData)
{
byte[] newData = new byte[8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitIP[i] >> 3] & (1 << (7 - (BitIP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}
void conversePermutation(byte[] inData)
{
byte[] newData = new byte[8];
for (int i = 0; i < 64; i++)
{
if ((inData[BitCP[i] >> 3] & (1 << (7 - (BitCP[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 8);
}
void expand(byte[] inData, byte[] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitExp[i] >> 3] & (1 << (7 - (BitExp[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}
void permutation(byte[] inData)
{
byte[] newData = new byte[4];
for (int i = 0; i < 32; i++)
{
if ((inData[BitPM[i] >> 3] & (1 << (7 - (BitPM[i] & 0x07)))) != 0)
{
newData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
Array.Copy(newData, inData, 4);
}
byte si(byte s, byte inByte)
{
int c = (inByte & 0x20) | ((inByte & 0x1e) >> 1) | ((inByte & 0x01) << 4);
return (byte)(sBox[s, c] & 0x0f);
}
void permutationChoose1(byte[] inData, byte[] outData)
{
Array.Clear(outData, 0, 7);
for (int i = 0; i < 56; i++)
{
if ((inData[BitPMC1[i] >> 3] & (1 << (7 - (BitPMC1[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}
void permutationChoose2(byte[] inData, byte[] outData)
{
Array.Clear(outData, 0, 6);
for (int i = 0; i < 48; i++)
{
if ((inData[BitPMC2[i] >> 3] & (1 << (7 - (BitPMC2[i] & 0x07)))) != 0)
{
outData[i >> 3] |= (byte)(1 << (7 - (i & 0x07)));
}
}
}
void cycleMove(byte[] inData, byte bitMove)
{
for (int i = 0; i < bitMove; i++)
{
inData[0] = (byte)((inData[0] << 1) | (inData[1] >> 7));
inData[1] = (byte)((inData[1] << 1) | (inData[2] >> 7));
inData[2] = (byte)((inData[2] << 1) | (inData[3] >> 7));
inData[3] = (byte)((inData[3] << 1) | ((inData[0] & 0x10) >> 4));
inData[0] = (byte)(inData[0] & 0x0f);
}
}
static readonly byte[] bitDisplace = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
void makeKey(byte[] inKey, byte[][] outKey)
{
byte[] outData56 = new byte[7];
byte[] key28l = new byte[4];
byte[] key28r = new byte[4];
byte[] key56o = new byte[7];
permutationChoose1(inKey, outData56);
key28l[0] = (byte)(outData56[0] >> 4);
key28l[1] = (byte)((outData56[0] << 4) | (outData56[1] >> 4));
key28l[2] = (byte)((outData56[1] << 4) | (outData56[2] >> 4));
key28l[3] = (byte)((outData56[2] << 4) | (outData56[3] >> 4));
key28r[0] = (byte)(outData56[3] & 0x0f);
key28r[1] = (byte)(outData56[4]);
key28r[2] = (byte)(outData56[5]);
key28r[3] = (byte)(outData56[6]);
for (int i = 0; i < 16; i++)
{
cycleMove(key28l, bitDisplace[i]);
cycleMove(key28r, bitDisplace[i]);
key56o[0] = (byte)((key28l[0] << 4) | (key28l[1] >> 4));
key56o[1] = (byte)((key28l[1] << 4) | (key28l[2] >> 4));
key56o[2] = (byte)((key28l[2] << 4) | (key28l[3] >> 4));
key56o[3] = (byte)((key28l[3] << 4) | (key28r[0]));
key56o[4] = (byte)(key28r[1]);
key56o[5] = (byte)(key28r[2]);
key56o[6] = (byte)(key28r[3]);
permutationChoose2(key56o, outKey[i]);
};
}
void encry(byte[] inData, byte[] subKey, byte[] outData)
{
byte[] outBuf = new byte[6];
byte[] buf = new byte[8];
expand(inData, outBuf);
for (int i = 0; i < 6; i++) outBuf[i] = (byte)(outBuf[i] ^ subKey[i]);
// outBuf xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
buf[0] = (byte)(outBuf[0] >> 2); //xxxxxx -> 2
buf[1] = (byte)(((outBuf[0] & 0x03) << 4) | (outBuf[1] >> 4)); // 4 <- xx xxxx -> 4
buf[2] = (byte)(((outBuf[1] & 0x0f) << 2) | (outBuf[2] >> 6)); // 2 <- xxxx xx -> 6
buf[3] = (byte)(outBuf[2] & 0x3f); // xxxxxx
buf[4] = (byte)(outBuf[3] >> 2); // xxxxxx
buf[5] = (byte)(((outBuf[3] & 0x03) << 4) | (outBuf[4] >> 4)); // xx xxxx
buf[6] = (byte)(((outBuf[4] & 0x0f) << 2) | (outBuf[5] >> 6)); // xxxx xx
buf[7] = (byte)(outBuf[5] & 0x3f); // xxxxxx
for (int i = 0; i < 8; i++) buf[i] = si((byte)i, buf[i]);
for (int i = 0; i < 4; i++) outBuf[i] = (byte)((buf[i * 2] << 4) | buf[i * 2 + 1]);
permutation(outBuf);
for (int i = 0; i < 4; i++) outData[i] = outBuf[i];
}
// inData, outData 都为 8 Bytes,否则出错
void desData(TDesMode desMode, byte[] inData, byte[] outData)
{
int i, j;
byte[] temp = new byte[4];
byte[] buf = new byte[4];
for (i = 0; i < 8; i++) outData[i] = inData[i];
initPermutation(outData);
if (desMode == TDesMode.dmEncry)
{
for (i = 0; i < 16; i++)
{
for (j = 0; j < 4; j++) temp[j] = outData[j]; //temp = Ln
for (j = 0; j < 4; j++) outData[j] = outData[j + 4]; //Ln+1 = Rn
encry(outData, SubKey[i], buf); //Rn ==Kn==> buf
for (j = 0; j < 4; j++) outData[j + 4] = (byte)(temp[j] ^ buf[j]); //Rn+1 = Ln^buf
};
for (j = 0; j < 4; j++) temp[j] = outData[j + 4];
for (j = 0; j < 4; j++) outData[j + 4] = outData[j];
for (j = 0; j < 4; j++) outData[j] = temp[j];
}
else if (desMode == TDesMode.dmDecry)
{
for (i = 15; i >= 0; i--)
{
for (j = 0; j < 4; j++) temp[j] = outData[j];
for (j = 0; j < 4; j++) outData[j] = outData[j + 4];
encry(outData, SubKey[i], buf);
for (j = 0; j < 4; j++) outData[j + 4] = (byte)(temp[j] ^ buf[j]);
};
for (j = 0; j < 4; j++) temp[j] = outData[j + 4];
for (j = 0; j < 4; j++) outData[j + 4] = outData[j];
for (j = 0; j < 4; j++) outData[j] = temp[j];
};
conversePermutation(outData);
}
#endregion
#region 十进制加密解密
/// <summary>
/// 字符串的Unicode形式加密
/// </summary>
/// <param name="Str">要加密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>加密过的字符串</returns>
public string EncryStrUnicode(string Str, string Key)
{
byte[] StrByte = new byte[8];
byte[] OutByte = new byte[8];
byte[] KeyByte = new byte[8];
if ((Str.Length > 0) && (Str[Str.Length - 1] == 0))
{
throw new ArgumentException("Error: the last char is NULL char.", "Str");
}
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
while (Str.Length % 8 != 0) Str += '\0';
for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);
StringBuilder StrResult = new StringBuilder();
byte[] tempBarry = Encoding.Unicode.GetBytes(Str);
for (int i = 0; i < tempBarry.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = tempBarry[i * 8 + j];
}
desData(TDesMode.dmEncry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};
return StrResult.ToString();
}
/// <summary>
/// 字符串的Ascii形式加密
/// </summary>
/// <param name="Str">要加密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>加密过的字符串</returns>
public string EncryStr(string Str, string Key)
{
byte[] StrByte = new byte[8];
byte[] OutByte = new byte[8];
byte[] KeyByte = new byte[8];
if ((Str.Length > 0) && (Str[Str.Length - 1] == 0))
{
throw new ArgumentException("Error: the last char is NULL char.", "Str");
}
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
while (Str.Length % 8 != 0) Str += '\0';
for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);
StringBuilder StrResult = new StringBuilder();
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmEncry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};
return StrResult.ToString();
}
/// <summary>
/// 解密字符串Unicode形式
/// </summary>
/// <param name="Str">加过密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>解密后的字符串</returns>
public string DecryStrUnicode(string Str, string Key)
{
byte[] StrByte = new byte[8];
byte[] OutByte = new byte[8];
byte[] KeyByte = new byte[8];
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);
byte[] tempArry = new byte[1024];
StringBuilder StrResult = new StringBuilder();
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmDecry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
tempArry[i * 8 + j] = OutByte[j];
}
};
string strTemp = Encoding.Unicode.GetString(tempArry);
return strTemp.ToString().TrimEnd('\0');
}
/// <summary>
/// 解密字符串 Ascii形式
/// </summary>
/// <param name="Str">加过密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>解密后的字符串</returns>
public string DecryStr(string Str, string Key)
{
byte[] StrByte = new byte[8];
byte[] OutByte = new byte[8];
byte[] KeyByte = new byte[8];
if (Key.Length < 8)
{
while (Key.Length < 8) Key += '\0';
}
for (int i = 0; i < 8; i++) KeyByte[i] = (byte)Key[i];
makeKey(KeyByte, SubKey);
StringBuilder StrResult = new StringBuilder();
for (int i = 0; i < Str.Length / 8; i++)
{
for (int j = 0; j < 8; j++)
{
StrByte[j] = (byte)Str[i * 8 + j];
}
desData(TDesMode.dmDecry, StrByte, OutByte);
for (int j = 0; j < 8; j++)
{
StrResult.Append((char)OutByte[j]);
}
};
return StrResult.ToString().TrimEnd('\0');
}
#endregion
#region 十六进制加密解密
/// <summary>
/// 十六进制形式的加密Ascii
/// </summary>
/// <param name="Str">要加密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>加密后的字符串</returns>
public string EncryStrHex(string Str, string Key)
{
string TempResult = EncryStr(Str, Key);
StringBuilder StrResult = new StringBuilder();
foreach (char c in TempResult)
{
StrResult.AppendFormat("{0:X2}", (int)c);
}
return StrResult.ToString();
}
/// <summary>
/// 十六进制形式的加密Unicode
/// </summary>
/// <param name="Str">要加密的字符串</param>
/// <param name="Key">密钥</param>
/// <returns>加密后的字符串</returns>
public string EncryStrHexUnicode(string Str, string Key)
{
string TempResult = EncryStrUnicode(Str, Key);
StringBuilder StrResult = new StringBuilder();
foreach (char c in TempResult)
{
StrResult.AppendFormat("{0:X2}", (int)c);
}
return StrResult.ToString();
}
/// <summary>
/// 十六进制形式的节密形式Ascii
/// </summary>
/// <param name="StrHex">要解密的字符串</param>
/// <param name="Key">密钥匙</param>
/// <returns>解密后的字符串</returns>
public string DecryStrHex(string StrHex, string Key)
{
if (StrHex.Length % 2 != 0)
{
throw new ArgumentException("Error: string length must be even.", "StrHex");
}
StringBuilder Str = new StringBuilder();
for (int i = 0; i < StrHex.Length; i += 2)
{
Str.Append((char)(Uri.FromHex(StrHex[i]) * 16 + Uri.FromHex(StrHex[i + 1])));
}
return DecryStr(Str.ToString(), Key);
}
/// <summary>
/// 十六进制形式的节密形式Unicode
/// </summary>
/// <param name="StrHex">要解密的字符串</param>
/// <param name="Key">密钥匙</param>
/// <returns>解密后的字符串</returns>
public string DecryStrHexUnicode(string StrHex, string Key)
{
if (StrHex.Length % 2 != 0)
{
throw new ArgumentException("Error: string length must be even.", "StrHex");
}
StringBuilder Str = new StringBuilder();
for (int i = 0; i < StrHex.Length; i += 2)
{
Str.Append((char)(Uri.FromHex(StrHex[i]) * 16 + Uri.FromHex(StrHex[i + 1])));
}
return DecryStrUnicode(Str.ToString(), Key);
}
#endregion
}
}
调用的代码如下:
static void Main(string[] args)
{
EncodeUnEncode des = new EncodeUnEncode();
string key = "bsImy@f";
string s0 = "a test of encode and decode";
System.Console.WriteLine("原串: {0}", s0);
string s1 = des.EncryStr(s0, key);
System.Console.WriteLine("加密: {0}", s1);
string s2 = des.DecryStr(s1, key);
System.Console.WriteLine("解密: {0}", s2);
string s3 = des.EncryStrHex(s0, key);
System.Console.WriteLine("HEX : {0}", s3);
string s4 = des.DecryStrHex(s3, key);
System.Console.WriteLine("解密: {0}", s4);
string ss0 = "a test of 加密和解密";
System.Console.WriteLine("原串: {0}", ss0);
string ss1 = des.EncryStrUnicode(ss0, key);
System.Console.WriteLine("加密: {0}", ss1);
string ss2 = des.DecryStrUnicode(ss1, key);
System.Console.WriteLine("解密: {0}", ss2);
string ss3 = des.EncryStrHexUnicode(ss0, key);
System.Console.WriteLine("HEX : {0}", ss3);
string ss4 = des.DecryStrHexUnicode(ss3, key);
System.Console.WriteLine("解密: {0}", ss4);
Console.ReadLine();
}

浙公网安备 33010602011771号