Пример #1
0
 /// <summary>
 ///     Метод, добавляющий модуль в многомодульное число.
 /// </summary>
 /// <param name="comparison"></param>
 /// <exception cref="InvalidOperationException">Модуль уже присутствует в числе</exception>
 public void AddModule(Comparison.LinearComparison comparison)
 {
     if (Modules.Contains(comparison.M))
     {
         throw new InvalidOperationException("Такой модуль уже присутствует в числе!");
     }
     Values.Add(comparison);
     Values = Values.OrderByDescending(element => element.M).ToList();
 }
Пример #2
0
 /// <summary>
 ///     Вычисление значения многочлена при заданном x в поле Zn. Возвращается вся получившаяся строка значений.
 ///     Используется схема Горнера.
 /// </summary>
 /// <param name="x"></param>
 /// <returns></returns>
 public int[] GetValueArray(int x)
 {
     Comparison.LinearComparison[] ResultArray = new Comparison.LinearComparison[Coefficients.Length];
     ResultArray[0] = new Comparison.LinearComparison((int)Coefficients[0].A, Module);
     for (int i = 1; i < Coefficients.Length; i++)
     {
         ResultArray[i] = new Comparison.LinearComparison((int)(ResultArray[i - 1].A * x + (int)Coefficients[i].A), Module);
     }
     return(ResultArray.Select(comparison => (int)comparison.A).ToArray());
 }
Пример #3
0
            /// <summary>
            ///     Тест Соловея-Штрассена. Имеет числа КарлМайкла
            /// </summary>
            /// <param name="source">Число, которое необходмио протестировать</param>
            /// <param name="count">Число прогонов теста</param>
            /// <returns></returns>
            public static PrimalityTestResult SSPT(BigInteger source, BigInteger count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста не должно быть меньше тестируемого числа.");
                }
                if (source == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                if (source == 1)
                {
                    return(PrimalityTestResult.Unknown);
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и число его прогонов должны быть положительными числами!");
                }

                //нам необходимо, чтобы число было нечетным, поэтому мы отсеиваем все четные числа.
                if (source % 2 == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 0; i < count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    //значение символа якоби
                    BigInteger jacobi = JacobiSymbol.Get(CurrentValue, source);
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, (source - 1) / 2).LeastModulo != jacobi)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                }

                return(PrimalityTestResult.Unknown);
            }
Пример #4
0
            /// <summary>
            ///     Fermat Primality Test - тест на основе теоремы Ферма. Имеет псевдопростые числа
            /// </summary>
            /// <param name="source">Число, которое необходимо проверить на простотоу</param>
            /// ///
            /// <param name="count">Число прогонов теста. Чем больше, тем точнее ответ.</param>
            /// <returns></returns>
            /// <exception cref="InvalidOperationException"></exception>
            public static PrimalityTestResult FPT(int source, int count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста должно быть меньше тестируемого числа.");
                }
                switch (source)
                {
                case 0:
                    return(PrimalityTestResult.Composite);

                case 1:
                    throw new InvalidOperationException("Единица не является ни простым, ни составным числом.");
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и количество прогонов должны быть положительными числами!");
                }

                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 1; i <= count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i - 1];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, source - 1).A != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                }

                return(PrimalityTestResult.Unknown);
            }
Пример #5
0
            /// <summary>
            ///     Тест Рабина Миллера. Имеет сильно псевдопростые числа
            /// </summary>
            /// <param name="source"></param>
            /// <param name="count"></param>
            /// <returns></returns>
            public static PrimalityTestResult MRPT(int source, int count)
            {
                if (count >= source)
                {
                    throw new InvalidOperationException("Число прогонов теста не должно быть меньше тестируемого числа.");
                }
                switch (source)
                {
                case 0:
                    return(PrimalityTestResult.Composite);

                case 1:
                    throw new InvalidOperationException("Единица не является ни простым, ни составным числом.");
                }

                if (source < 0 || count <= 0)
                {
                    throw new InvalidOperationException(
                              "Тестируемое число и число его прогонов должны быть положительными числами!");
                }

                //нам необходимо, чтобы число было нечетным, поэтому мы отсеиваем все четные числа.
                if (source % 2 == 0)
                {
                    return(PrimalityTestResult.Composite);
                }
                int t = source - 1;
                int s = 0;

                while (t % 2 == 0)
                {
                    t /= 2;
                    s++;
                }
                //n-1 = (2^s) * t


                BigInteger[] RestVariants = RD.UniformDistribution(2, source - 1, count);
                //отрезок [2,n-1]
                for (int i = 0; i < count; i++)
                {
                    BigInteger CurrentValue = RestVariants[i];
                    if (AdvancedEuclidsalgorithm.GCDResult(CurrentValue, source) != 1)
                    {
                        return(PrimalityTestResult.Composite);
                    }
                    //значение символа якоби
                    Comparison.LinearComparison comparison = new Comparison.LinearComparison(CurrentValue, source);
                    if (BigInteger.Abs((comparison = Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, t))
                                       .LeastModulo) == 1)
                    {
                        continue;
                    }

                    while (s != 1)
                    {
                        comparison = Comparison.MultiplicativeInverse.BinaryPowLinearComparison(comparison, 2);
                        if (comparison.LeastModulo == -1)
                        {
                            break;
                        }
                        if (--s == 0)
                        {
                            return(PrimalityTestResult.Composite);
                        }
                    }
                }

                return(PrimalityTestResult.Unknown);
            }