【问题标题】:How to calculate the modular multiplicative inverse for the Affine Cipher如何计算仿射密码的模乘逆
【发布时间】:2013-10-30 09:05:30
【问题描述】:

我正在尝试创建一个执行仿射密码的小软件,这意味着 K1 和字母表中的字母数量(使用 m 表示这个数字)必须互质,即gcd(k1, m) == 1

基本上是这样的:

我有一个明文:

我有 K1:7

我有 K2:5

数字格式的明文是: 8 5 25

8 - 来自 h(字母表中的位置)和 ** ey

5 25** 相同

加密:7 13 18

公式是:

k1 * 8 + k2 mod 27 = 7

k1 * 5 + k2 mod 27 = 13

k1 * 25 + k2 mod 27 = 18

我有一个可以加密的函数,但我不知道如何解密。

例如我有 7 代表 h。我想再次找回数字 8,知道 7、k1 和 k2。

你们有什么想法吗?

你输入 k1、k2、结果的一些函数(例如 7,对于 h),它给了我 8,但我真的不知道如何反转这个。

加密函数是这样的:

public List<int> get_crypted_char(string[] strr)
        {
            List<int> l = new List<int>();
            int i;
            for (i = 0; i < strr.Length; i++)
            {
                int ch = int.Parse(strr[i]);
                int numberback = k1 * ch + 5;
                numberback = (numberback % 27);
                l.Add(numberback);
            }
            return l;
        }

其中:string[] strr 是一个包含明文的字符串。 函数示例: get_crypted_char({"e","c","b"})

结果将是这样的列表 {"5","3","2"}

更新: 这是来自维基百科的关于这种加密和解密的链接,但是......我真的不明白“如何” http://en.wikipedia.org/wiki/Affine_cipher

【问题讨论】:

  • 你的问题不清楚 IMO..
  • 你有加密代码吗?我认为它更容易阅读。
  • 过去有人问过并回答过:stackoverflow.com/a/10133236/146205。没有真正的方法可以取回它,例如 8 mod 35 mod 3 都等于 2
  • 知道 mod 操作的结果并不能帮助您找到操作数。例如61 mod 27 = 7,还有34 mod 27 = 7,甚至7 mod 27 = 7。那么你怎么知道无数种可能性中的哪一种是正确的呢?
  • 链接有解密算法。为什么要使用 27?

标签: c# .net math modulo


【解决方案1】:

这是不可能的(一般情况下,对于仿射密码,请参阅下面的更新)。这就是模块操作在安全算法中如此频繁使用的原因——它是不可逆的。但是,我们为什么不试试呢?

result = (k1 * input + k2) % 27 (*1)

我们取第一个字母:

result = (7 * 8 + 5) % 27 = 7

这很酷。现在,因为我们说过:

result = (k1 * input + k2) % 27

以下也是正确的:

k1 * input + k2 = 27 * div + result (*2)

在哪里

div = (k1 * input + k2) / 27 (integral division)

很明显(如果a % b = c,那么a = b*n + c,其中n是a/b的整数除法)。

您知道 k1(即 7)、k2(5)和 result(7)的值。因此,当我们将这些值代入 (*2) 时,我们会得到以下结果:

7 * input + 5 = 27 * div + 7 //You need to solve this

如您所见,这是不可能解决的,因为您还需要知道积分除法的结果 - 将其翻译成您的函数语言,您需要

numberback / 27

这是未知的。所以答案是:你不能反转你的函数的结果,只使用它返回的输出


** 更新 **


我过于关注问题的标题,所以上面的答案并不完全正确。但是,我决定不删除它,而是写一个更新。

因此,针对您的特定情况(仿射密码)的答案是:是的,您可以反转它。

正如您在 wiki 上看到的,仿射密码的解密函数用于以下加密函数:

E(input) = a*input + b mod m

定义为:

D(enc) = a^-1 * (enc - b) mod m

这里唯一可能的问题是 a^-1 的计算,它是模乘逆。

wiki 上了解它,我将仅提供示例。

在你的情况下 a = k1 = 7 和 m = 27。所以:

7^-1 = p mod 27
7p = 1 mod 27

也就是说,你需要找到满足以下条件的p:7p % 27 = 1。 p 可以使用扩展欧几里得算法计算,我计算为 4 (4 * 7 = 28, 28 % 27 = 1)。

检查,现在是否可以破译您的输出:

E(8) = 7*8 + 5 mod 27 = 7

D(7) = 4 * (7 - 5) mod 27 = 8

希望有帮助:)

【讨论】:

  • @icebox19 答案不正确。密码需要互质。
  • 您的假设与@Stefan 相同,数字不是随机的。 k1m (27) 互质,别忘了。
【解决方案2】:

请注意,其他答案没有考虑手头的算法是仿射密码,即手头有一些条件,最重要的是k1m的互质状态。

在你的情况下是:

m = 27; // letters in your alphabet
k1 = 7; // coprime with m
k2 = 5; // no reqs here, just that a value above 27 is the same as mod 27 of that value

int Encrypt(int letter) {
  return ((letter * k1) + k2) % m;
}

int Decrypt(int letter) {
  return ((letter - k2) * modInverse(k1, m)) % m;
}

Tuple<int, Tuple<int, int>> extendedEuclid(int a, int b)
{
  int x = 1, y = 0;
  int xLast = 0, yLast = 1;
  int q, r, m, n;
  while (a != 0)
  {
    q = b / a;
    r = b % a;
    m = xLast - q * x;
    n = yLast - q * y;
    xLast = x; yLast = y;
    x = m; y = n;
    b = a; a = r;
  }
  return new Tuple<int, Tuple<int, int>>(b, new Tuple<int, int>(xLast, yLast));
}

int modInverse(int a, int m)
{
  return (extendedEuclid(a, m).Item2.Item1 + m) % m;
}

ModInverse 实现取自 http://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse/

【讨论】:

    【解决方案3】:

    我创建了一个程序,它可以告诉某些东西的模逆。我会让你使用它。它张贴在下面。

    # Cryptomath Module
    
    
    def gcf(a, b):
        # Return the GCD of a & b using Euclid's Algorithm
        while a != 0:
            a, b = b % a, a
        return b
    
    
    def findModInverse(a, m):
        # Return the modular inverse of a % m, which is
        # the number x such that a*x % m = 1
    
        if gcf(a, m) != 1:
            return None # No mode inverese if a & m aren't relatively prime
    
        # Calculate using the Extended Euclidean Algorithm:
        u1, u2, u3 = 1, 0, a
        v1, v2, v3 = 0, 1, m
        while v3 != 0:
            q = u3 // v3 # // is the integer division operator
            v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q *
    v3), v1, v2, v3
        return u1 % m
    

    注意:模逆是使用扩展欧几里得算法找到的。这是它的维基百科条目:http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm

    注意:这需要作为模块导入才能使用。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多