Example #1
0
        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);
        }
Example #2
0
        /// <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)}");
        }
Example #3
0
        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));
        }