Вы также можете посмотреть модуль gmpy . Это интерфейс между Python и библиотекой множественной точности GMP. gmpy предоставляет функцию инвертирования, которая делает именно то, что вам нужно:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Обновленный ответ
Как отмечает @hyh, gmpy.invert()
возвращается 0, если обратного не существует. Это соответствует поведению функции GMP mpz_invert()
. gmpy.divm(a, b, m)
обеспечивает общее решение проблемы a=bx (mod m)
.
>>> gmpy.divm(1, 1234567, 1000000007)
mpz(989145189)
>>> gmpy.divm(1, 0, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 9)
mpz(7)
divm()
вернет решение, когда gcd(b,m) == 1
и вызовет исключение, когда мультипликативная обратная функция не существует.
Отказ от ответственности: я в настоящее время поддерживаю библиотеку gmpy.
Обновленный ответ 2
gmpy2 теперь корректно вызывает исключение, если обратное не существует:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
pow
функции для этого:y = pow(x, -1, p)
. См. Bugs.python.org/issue36027 . Прошло всего 8,5 лет от вопроса до того, как решение появилось в стандартной библиотеке!