C#ModInverse函数

时间:2011-09-20 10:30:37

标签: c# c#-4.0 modulo

是否有内置函数可以让我计算(mod n)的模逆? 例如19 ^ -1 = 11(mod 30),在这种情况下为19 ^ -1 == -11 == 19;

5 个答案:

答案 0 :(得分:13)

由于.Net 4.0+使用特殊的模块化算术函数ModPow(生成“XY modulo Z”)来实现BigInteger,因此您不需要第三方库来模拟ModInverse。如果n是素数,那么您需要做的就是计算:

a_inverse = BigInteger.ModPow(a, n - 2, n)

有关详细信息,请查看维基百科:Modular multiplicative inverse,第Using Euler's theorem部分,特殊情况“当m是素数”时。顺便说一句,有一个更新的SO主题:1/BigInteger in c#,采用相同的方法suggested by CodesInChaos

答案 1 :(得分:6)

int modInverse(int a, int n) 
{
    int i = n, v = 0, d = 1;
    while (a>0) {
        int t = i/a, x = a;
        a = i % x;
        i = x;
        x = d;
        d = v - t*x;
        v = x;
    }
    v %= n;
    if (v<0) v = (v+n)%n;
    return v;
}

答案 2 :(得分:3)

BouncyCastle加密库具有BigInteger实现,该实现具有大多数模块化算术功能。它位于Org.BouncyCastle.Math命名空间中。

答案 3 :(得分:2)

这是塞缪尔·艾伦(Samuel Allan)的algorithm的精巧版本。 TryModInverse方法返回一个bool值,该值指示是否存在该数字和模的模乘逆。

public static bool TryModInverse(int number, int modulo, out int result)
{
    if (number < 1) throw new ArgumentOutOfRangeException(nameof(number));
    if (modulo < 2) throw new ArgumentOutOfRangeException(nameof(modulo));
    int n = number;
    int m = modulo, v = 0, d = 1;
    while (n > 0)
    {
        int t = m / n, x = n;
        n = m % x;
        m = x;
        x = d;
        d = checked(v - t * x); // Just in case
        v = x;
    }
    result = v % modulo;
    if (result < 0) result += modulo;
    if ((long)number * result % modulo == 1L) return true;
    result = default;
    return false;
}

答案 4 :(得分:0)

没有用于获取逆mod的库,但可以使用以下代码来获取它。

>>> {k: v for k, *v in zip(*my_list)}
{'key1': [1, 'a'], 'key2': [2, 'b']}