C# 如何计算仿射密码的模乘逆

C# 如何计算仿射密码的模乘逆,c#,.net,math,modulo,C#,.net,Math,Modulo,我正在尝试创建一个仿射密码的小软件,这意味着K1和字母表中的字母数量(使用m表示这个数字)必须是互质的,即gcd(K1,m)==1 基本上是这样的: 我有一条明文:嘿 我有K1:7 我有K2:5 数字格式的明文是: 8525 8-从h(字母表中的位置)开始,以及** 5 25**对于e和y 加密:71318 公式如下: k1*8+k2模式27=7 k1*5+k2模式27=13 k1*25+k2模式27=18 我有一个加密这个的函数,但我不知道如何解密 例如,我用7表示h。我想把数字8拿回来,知道

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

基本上是这样的:

我有一条明文:

我有K1:7

我有K2:5

数字格式的明文是: 8525

8-从h(字母表中的位置)开始,以及** 5 25**对于ey

加密:71318

公式如下:

k1*8+k2模式27=7

k1*5+k2模式27=13

k1*25+k2模式27=18

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

例如,我用7表示h。我想把数字8拿回来,知道7,k1和k2

你们有什么想法吗

一些函数,你输入k1,k2,result(例如,h为7),它会返回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;
        }
公共列表获取加密字符(字符串[]strr)
{
列表l=新列表();
int i;
对于(i=0;i
其中:string[]strr是包含纯文本的字符串。 函数示例: 获取加密字符({“e”、“c”、“b”})

结果将是这样一个列表{“5”、“3”、“2”}

更新: 这里有一个来自维基百科的关于加密和解密的链接,但是。。。我真的不明白“怎么做”

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

result = (k1 * input + k2) % 27 (*1)
让我们看第一个字母:

result = (7 * 8 + 5) % 27 = 7
那很酷。现在,因为我们说过:

result = (k1 * input + k2) % 27
以下也是事实:

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

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

您知道k1(即7)、k2(5)和结果(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的计算,它是模乘逆

请继续阅读,我只提供一个例子

在你的例子中,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

希望有帮助:)

请注意,其他答案没有考虑到当前的算法是仿射密码,即当前有一些条件,最重要的条件是
k1
m
的互质状态

在您的情况下,它将是:

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;
}
m=27;//字母表中的字母
k1=7;//与m的互质
k2=5;//这里没有要求,只是高于27的值与该值的mod 27相同
整数加密(整数字母){
返回((字母*k1)+k2)%m;
}
整数解密(整数字母){
返回((字母-k2)*修改(k1,m))%m;
}
元组扩展欧几里得(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;
}
返回新元组(b,新元组(xLast,yLast));
}
int modInverse(int a,int m)
{
返回(扩展欧几里得(a,m).Item2.Item1+m)%m;
}

ModInverse实现取自。

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

# 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
注:模逆是使用扩展的欧几里德算法求出的。以下是它的维基百科条目:


注意:这需要作为要使用的模块导入。希望有帮助。

我不清楚您的问题。您有加密代码吗?我认为它更容易阅读。这在过去已经被问过并回答过了:。没有真正的方法可以恢复,例如
8 mod 3
5 mod 3
都等于
2
。知道mod运算的结果并不能帮助您找到操作数。例如
61 mod 27=7
但也
34 mod 27=7
甚至
7 mod 27=7
。那么,您如何知道千千万万种可能性中的哪一种是正确的呢?该链接具有解密算法。你为什么用27呢?@icebox19答案是不正确的。密码需要使用coprimes。您的假设与@Stefan相同,数字不是随机的
k1
m
(27)是互质,不要忘记这一点。
# 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