public List <char> Encrypt(List <char> plain) { // 拷贝plain var copy = new List <char>(); for (int i = 0; i < plain.Count; i++) { copy.Add(plain[i]); } // 将终结符转义,即将一个终结符换成两个连续的终结符 for (int i = 0; i < copy.Count; i++) { if (copy[i] == Transfer_Char) { copy.Insert(i, Transfer_Char); i++; } } // 在数据的最后加上终结符 copy.Add(Transfer_Char); // 检查数据总长度,如果最后一组数量不够,需要填充数据 int appendLength = copy.Count % groupLength;// 填充数 if (appendLength != 0) { appendLength = groupLength - appendLength; } for (int i = 0; i < appendLength; i++) { copy.Add(Append_Char); } // TODO Delete //PrintList(copy, "[加密前]"); int groupNums = copy.Count / groupLength + ((copy.Count % groupLength) == 0 ? 0 : 1); // 总分组数 List <char> result = new List <char>(); // 结果 for (int i = 0; i < groupNums; i++) { // 使用加密矩阵将分组加密,然后添加到结果中 result.AddRange(MatrixIntGF26.MultiplyMod26(copy.GetRange(i * groupLength, groupLength).ToArray(), EKEY)); } // TODO Delete //PrintList(result, "[加密后]"); return(result); }
/// <summary> /// 初始化 /// </summary> /// <param name="ekey">密钥,必须是可逆的方阵</param> public HillCipher(int[,] ekey) { this.EKEY = new MatrixIntGF26(ekey); if (!this.EKEY.HasInverse()) { throw new Exception("加密矩阵无法在有限域内求得逆矩阵"); } this.DKEY = EKEY.Inverse(); this.groupLength = ekey.GetLength(0); // 如果执行到这里,已经说明矩阵是方阵 // TODO Delete //Debug.WriteLine($"{EKEY.ToString()}{System.Environment.NewLine}" + // $"x{System.Environment.NewLine}{DKEY.ToString()}{System.Environment.NewLine}" + // $"={System.Environment.NewLine}{EKEY.MultifyMod(DKEY)}"); }
public List <char> Decrypt(List <char> cipher) { // TODO Delete //PrintList(cipher, "[解密前]"); if (cipher.Count % groupLength != 0) { throw new FormatException("密文的格式出错,请检查是否缺失数据"); } // 解密 int groupNums = cipher.Count / groupLength; // 总分组数 List <char> result = new List <char>(); // 结果 for (int i = 0; i < groupNums; i++) { // 使用加密矩阵将分组解密,然后添加到结果中 result.AddRange(MatrixIntGF26.MultiplyMod26(cipher.GetRange(i * groupLength, groupLength).ToArray(), DKEY)); } // TODO Delete //PrintList(result, "[解密后]"); // 去冗余,去除终结符之后的数据 var index = result.LastIndexOf(Transfer_Char); if (index == -1) { throw new Exception("数据出错,或者数据和希尔密码的密钥不匹配"); } result.RemoveRange(index, result.Count - index); // 合并连续的两个终结符 for (int i = 1; i < result.Count; i++) { if (result[i] == Transfer_Char) { if (result[i - 1] == Transfer_Char) { result.RemoveAt(i); } } } return(result); }
/// <summary> /// 向量和矩阵相乘 /// </summary> /// <param name="vector">向量</param> /// <param name="matrix">矩阵</param> /// <returns>乘积</returns> public static char[] MultiplyMod26(char[] vector, MatrixIntGF26 matrix) { if (vector.Length != matrix.row) { throw new Exception("无法进行乘法运算,向量的维度和矩阵的行数不相等"); } var result = new char[vector.Length]; double temp; for (int i = 0; i < result.Length; i++) { temp = 0; for (int j = 0; j < matrix.column; j++) { temp += vector[j] * matrix.elements[j, i]; } result[i] = (char)Mod(SolveDouble(temp)); } return(result); }
/// <summary> /// 两个矩阵相乘 /// </summary> /// <param name="b"></param> /// <returns></returns> public MatrixIntGF26 MultifyMod(MatrixIntGF26 b) { if (this.column != b.row) { throw new Exception($"{this.row}行{this.column}列和{b.row}行{b.column}列的两个矩阵无法进行计算"); } var result = new int[this.row, b.column]; for (int i = 0; i < this.row; i++) { for (int j = 0; j < b.column; j++) { double temp = 0; for (int k = 0; k < this.column; k++) { temp += this.elements[i, k] * b.elements[k, j]; } result[i, j] = Mod(SolveDouble(temp)); } } return(new MatrixIntGF26(result)); }