Как вычислить модуль больших количеств?

Как вычислить модуль 5^55 модуль 221 без большого использования калькулятора?

Я предполагаю, что существуют некоторые простые принципы в теории чисел в криптографии для вычисления таких вещей.

67
задан pimvdb 18 August 2011 в 19:29
поделиться

5 ответов

Хорошо, итак, вы хотите рассчитать a^b mod m. Сначала мы применим наивный подход, а затем посмотрим, как мы сможем его усовершенствовать.

Сначала уменьшим a^b mod m. Это значит, найти число a1 так, чтобы 0 <= a1 < m и a = a1 mod m. Затем несколько раз в цикле умножить на a1 и снова уменьшить mod m. Таким образом, в псевдокоде:

a1 = a reduced mod m
p = 1
for(int i = 1; i <= b; i++) {
    p *= a1
    p = p reduced mod m
}

делая это, мы избегаем чисел больше m^2. Это и есть ключ. Причина, по которой мы избегаем чисел больше m^2, заключается в том, что на каждом шаге 0 <= p < m и 0 <= a1 < m.

В качестве примера вычислим 5^55 mod 221. Во-первых, 5 уже уменьшено mod 221.

  1. 1 * 5 = 5 мод 221
  2. 5 * 5 = 25 мод 221
  3. 25 * 5 = 125 мод 221
  4. 125 * 5 = 183 мод 221
  5. 183 * 5 = 31 мод 221
  6. 31 * 5 = 155 мод 221
  7. 155 * 5 = 112 мод 221
  8. 112 * 5 = 118 mod 221
  9. 118 * 5 = 148 mod 221
  10. 148 * 5 = 77 mod 221
  11. 77 * 5 = 164 mod 221
  12. 164 * 5 = 157 mod 221
  13. 157 * 5 = 122 mod 221
  14. 122 * 5 = 168 mod 221
  15. 168 * 5 = 177 мод 221
  16. 177 * 5 = 1 мод 221
  17. 1 * 5 = 5 мод 221
  18. 5 * 5 = 25 мод 221
  19. 25 * 5 = 125 мод 221
  20. 125 * 5 = 183 мод 221
  21. 183 * 5 = 31 мод 221
  22. 31 * 5 = 155 мод 221
  23. 155 * 5 = 112 мод 221
  24. 112 * 5 = 118 мод 221
  25. 118 * 5 = 148 мод 221
  26. 148 * 5 = 77 мод 221
  27. 77 * 5 = 164 мод 221
  28. 164 * 5 = 157 мод 221
  29. 157 * 5 = 122 мод 221
  30. 122 * 5 = 168 мод 221
  31. 168 * 5 = 177 мод 221
  32. 177 * 5 = 1 мод 221
  33. 1 * 5 = 5 мод 221
  34. 5 * 5 = 25 мод 221
  35. 25 * 5 = 125 мод 221
  36. 125 * 5 = 183 мод 221
  37. 183 * 5 = 31 мод 221
  38. 31 * 5 = 155 мод 221
  39. 155 * 5 = 112 мод 221
  40. 112 * 5 = 118 мод 221
  41. 118 * 5 = 148 мод 221
  42. 148 * 5 = 77 mod 221
  43. 77 * 5 = 164 mod 221
  44. 164 * 5 = 157 mod 221
  45. 157 * 5 = 122 mod 221
  46. 122 * 5 = 168 mod 221
  47. 168 * 5 = 177 mod 221
  48. 177 * 5 = 1 mod 221
  49. 1 * 5 = 1 mod 221
  50. 1 * 5 = 1 mod 221
  51. 1 5 mod 221
  52. 5 * 5 = 25 mod 221
  53. 25 * 5 = 125 mod 221
  54. 125 * 5 = 183 mod 221
  55. 183 * 5 = 31 mod 221
  56. 31 * 5 = 155 mod 221
  57. 155 * 5 = 112 mod 221

Следовательно, 5^55 = 112 mod 221.

Теперь мы можем улучшить это, используя экспоненцию, установив квадрат ; это известный трюк, в котором мы сводим экспоненцию к требованию только log b умножения вместо b. Обратите внимание, что при использовании алгоритма, описанного мною выше, экспоненцирование путем улучшения квадратуры, вы получаете двоичный метод справа налево .

a1 = a reduced mod m
p = 1
while (b > 0) {
     if (b is odd) {
         p *= a1
         p = p reduced mod m
     }
     b /= 2
     a1 = (a1 * a1) reduced mod m
}

Таким образом, since 55 = 110111 in binary

  1. 1 * (5^1 mod 221) = 5 mod 221
  2. 5 * (5^2 mod 221) = 125 mod 221
  3. 125 * (5^4 mod 221) = 112 mod 221
  4. 112 * (5^16 mod 221) = 112 mod 221
  5. 112 * (5^32 mod 221) = 112 mod 221

Следовательно, ответ 5^55 = 112 mod 221. Причина, по которой это работает, в том, что

55 = 1 + 2 + 4 + 16 + 32

так

5^55 = 5^(1 + 2 + 4 + 16 + 32) mod 221
     = 5^1 * 5^2 * 5^4 * 5^16 * 5^32 mod 221
     = 5 * 25 * 183 * 1 * 1 mod 221
     = 22875 mod 221
     = 112 mod 221

на шаге, где мы вычисляем 5^1 mod 221, 5^2 mod 221 и т.д., мы отмечаем, что 5^(2^k) = 5^(2^(k-1)) * 5^(2^(k-1)) потому что 2^k = 2^(k-1) + 2^(k-1) так что сначала мы можем вычислить 5^1 и уменьшить мод 221, затем поставить квадрат и уменьшить мод 221 до получения 5^2 мод 221 и т.д. и т.п.

Вышеуказанный алгоритм формализует эту идею.

94
ответ дан 24 November 2019 в 14:33
поделиться

Чтобы добавить в ответ Джасона:

Вы можете ускорить процесс вверх (который может быть полезен для очень больших показателей) с использованием двоичного расширения показателя. Первый рассчитал 5, 5 ^ 2, 5 ^ 4, 5 ^ 8 мод 221 - вы делаете это повторным квадратом:

 5^1 = 5(mod 221)
 5^2 = 5^2 (mod 221) = 25(mod 221)
 5^4 = (5^2)^2 = 25^2(mod 221) = 625 (mod 221) = 183(mod221)
 5^8 = (5^4)^2 = 183^2(mod 221) = 33489 (mod 221) = 118(mod 221)
5^16 = (5^8)^2 = 118^2(mod 221) = 13924 (mod 221) = 1(mod 221)
5^32 = (5^16)^2 = 1^2(mod 221) = 1(mod 221)

Теперь мы можем написать

55 = 1 + 2 + 4 + 16 + 32

so 5^55 = 5^1 * 5^2 * 5^4 * 5^16 * 5^32 
        = 5   * 25  * 625 * 1    * 1 (mod 221)
        = 125 * 625 (mod 221)
        = 125 * 183 (mod 183) - because 625 = 183 (mod 221)
        = 22875 ( mod 221)
        = 112 (mod 221)

, вы можете увидеть, как для очень больших показателей это будет намного быстрее (я Поверьте, это журнал, а не линейный в B, но не уверен.)

28
ответ дан 24 November 2019 в 14:33
поделиться

То, что вы ищете, является модульная экспоненция, специально модульная бинарная экспоненция. Это ссылка в Википедии имеет псевдокод.

2
ответ дан 24 November 2019 в 14:33
поделиться

Как правило, программирование ограничения является хорошим подходом к этому типу задачи планирования. Поиски на «Ограниченное программирование» и планирование или «планирование на основе ограничений» как в пределах переполнения стека, так и в Google, будут генерировать некоторые хорошие ссылки. Это не невозможно - это просто немного трудно думать при использовании традиционных методов оптимизации, таких как линейная или целочисленная оптимизация. Один вывод будет - существует ли график, который удовлетворяет всем требованиям? Что, само по себе, очевидно полезно.

Удачи!

-121--799784-

Китайская теорема остатки приходит в голову как начальная точка, как 221 = 13 * 17. Итак, сломайте это на 2 части, которые объединяются в конце, один для мода 13 и Один для мода 17. Во-вторых, я считаю, что есть некоторые доказательства ^ (P-1) = 1 MOD P для всех ненулевых A, который также помогает уменьшить вашу проблему, поскольку 5 ^ 55 становится 5 ^ 3 для случая мода 13 13 * 4 = 52. Если вы посмотрите под тему «конечных полей», вы можете найти несколько хороших результатов о том, как решить это.

Редактировать: причина, по которой я упоминаю факторы, состоит в том, что это создает способ факторов нуля в ненулевые элементы, как если бы вы пробовали что-то вроде 13 ^ 2 * 17 ^ 4 MOD 221, ответ равен нулю с 13 * 17 = 221 Многие большие числа не будут иметь преимущества, хотя есть способы найти большие простые числа, так как они много используются в криптографии и других областях в пределах математики.

2
ответ дан 24 November 2019 в 14:33
поделиться

Почему вы не можете просто использовать трубы ?

Например, для автоматического автоматического принятия используйте да , который просто выводит неверный поток y .

yes | rm *.txt


(источник: wikimedia.org )

-121--1562217-

Набор кода и эта запись блога предоставляют подробные способы повышения производительности приложения.

Скомпилированный запрос повысит производительность приложения, но не имеет ничего общего с ASP.NET MVC. Это ускорит каждое приложение БД, так что дело не в MVC.

-121--602920-

Это часть кода I, созданного для проверки IBAN. Не стесняйтесь использовать.

    static void Main(string[] args)
    {
        int modulo = 97;
        string input = Reverse("100020778788920323232343433");
        int result = 0;
        int lastRowValue = 1;

        for (int i = 0; i < input.Length; i++)
        {
            // Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number                                                                        
            if (i > 0)
            {
                lastRowValue = ModuloByDigits(lastRowValue, modulo);
            }
            result += lastRowValue * int.Parse(input[i].ToString());
        }
        result = result % modulo;
        Console.WriteLine(string.Format("Result: {0}", result));            
    }

    public static int ModuloByDigits(int previousValue, int modulo)
    {
        // Calculating the modulus of a large number Wikipedia http://en.wikipedia.org/wiki/International_Bank_Account_Number                        
        return ((previousValue * 10) % modulo);
    }
    public static string Reverse(string input)
    {
        char[] arr = input.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }
2
ответ дан 24 November 2019 в 14:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: