【问题标题】:How to perform multiplicative inverse in C# [duplicate]如何在 C# 中执行乘法逆运算 [重复]
【发布时间】:2021-06-13 03:22:25
【问题描述】:

我有以下代码:

BigInteger b = new BigInteger(12345678912345678912);
var modedInteger = b * 3712931 % (2 ^ 64);

鉴于此,我将如何获得b 来自 modedInteger 的值?我看到我们可以使用BigInteger.ModPow(),但我不确定...

【问题讨论】:

  • 不,它没有回答如何用乘法得到 b,在我的情况下,我将 b 与 3712931 相乘
  • ...将结果除以 3712931?
  • 但是我在我的 Mod.Pow() 函数中放了什么?我试着放他们放的东西,但我得到 1 作为输出
  • 注意,2 ^ 64 == 66,因为^ 代表 xor(eXlusive OR),不适用于“2 的 64 次方”
  • “我看到我们可以使用 BigInteger.ModPow() 但我不确定” -- 为什么不呢?你在哪里“看到”了,为什么你“不确定”?您的问题缺少重要的细节,无法解释您尝试了什么、为什么没有奏效以及具体您需要什么帮助。

标签: c# biginteger modulo


【解决方案1】:

嗯,你可以尝试从Extended Euclid Algorithm开始,例如(让它实现为扩展方法

    public static (BigInteger LeftFactor,
               BigInteger RightFactor,
               BigInteger Gcd) Egcd(this BigInteger left, BigInteger right) {
      BigInteger leftFactor = 0;
      BigInteger rightFactor = 1;

      BigInteger u = 1;
      BigInteger v = 0;
      BigInteger gcd = 0;

      while (left != 0) {
        BigInteger q = right / left;
        BigInteger r = right % left;

        BigInteger m = leftFactor - u * q;
        BigInteger n = rightFactor - v * q;

        right = left;
        left = r;
        leftFactor = u;
        rightFactor = v;
        u = m;
        v = n;

        gcd = right;
      }

      return (LeftFactor: leftFactor,
              RightFactor: rightFactor,
              Gcd: gcd);
    }

然后你可以继续mod inversionmod除法

    public static BigInteger ModInversion(this BigInteger value, BigInteger modulo) {
      var egcd = Egcd(value, modulo);

      if (egcd.Gcd != 1)
        throw new ArgumentException("Invalid modulo", nameof(modulo));

      BigInteger result = egcd.LeftFactor;

      if (result < 0)
        result += modulo;

      return result % modulo;
    }

    public static BigInteger ModDivision(
      this BigInteger left, BigInteger right, BigInteger modulo) =>
           (left * ModInversion(right, modulo)) % modulo;

最后,你的测试:

  BigInteger b = new BigInteger(12345678912345678912);

  //DONE: Please, note that ^ stands for XOR, so 2 ^ 64 == 66
  BigInteger mod = BigInteger.Pow(2, 64);

  var modedInteger = b * 3712931 % mod;

  BigInteger result = modedInteger.ModDivision(3712931, mod);

  Console.Write(result);

结果:

 12345678912345678912

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 2015-02-17
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多