代码

时间:2015-09-29 13:58:49

标签: java multiplication modulus inverse

我已经阅读了很多关于这个主题的内容,关于欧几里德算法,我在这里有所需的所有参考资料:

(我的问题的最佳来源) - > Math Explanation

另一个很好的例子 - > Math Explanation 2

Wiki - > Extended Euclidean

添加值的绝佳答案 - > Add Operation

这是我完全失去它的地方 - > AFFINE CIPHERS

但是,在所有这些来源中,我仍然无法理解如何通过代码(或伪代码)实现它,或者至少找不到编写它的方法。

所以我会写下基础知识,让我们假设我有这个公式:

  

(x * key)%mod =结果
  0< = X< = mod
0< = key< = mod
0< =结果< = mod

mod 常量
*表示乘法操作
表示余数操作(编辑以澄清)
x 结果 动态

我想创建一个公式,它将通过Java提供x代码。

为我计算结果的函数是:

private int MultModulus(int num, int key, int mod)
{
    return (num * key) % mod;
}

我怎样才能找到X?我应该写什么来计算呢?这是我不理解的地方,让我们假设我的功能签名是:

private int InverseMultModulus(int result, int key, int mod)
{
    x = ...
    return x;
}

2 个答案:

答案 0 :(得分:1)

运行MultModulus,但在[0,mod]中用X迭代以返回答案并将它们存储在数组中。

for (int i=0;i<mod;i++){
    if (MultModulus(i, key, mod) == result){
       // store answer in array
    }
}

return array;

答案 1 :(得分:1)

如果正如@ ergonaut的回答评论中所述,您需要能够仅针对相对较少的原始值x来解决此问题,并且mod的值相对较小。 1}},然后一种合理的方法是提前构建解码表:对每个可能的x执行正向计算,并将起始x记录在数组中,索引在{{1 }}。然后,您可以执行简单的数组查找,以获得每个结果的result。对于足够长的值序列中的每个值(即,足够长的加密消息中的字符),这肯定会优于计算x。当然,如果您以Vignere密码的精神(即使用多字节密钥)执行此操作,则会将预先计算解码表所需的输入长度乘以获胜。

但请注意,使用您描述的函数来定义可行的密码取决于每个有效的输入值,从而产生不同的结果。但是,正如我们已经讨论过的,xkey的某些组合会产生重复的结果。此外,如果可能结果值的空间与可能输入值的空间大小相同,则必须选择modkey的组合,这会导致所有可能的mod值正在使用,否则你无法避免重复。

如果要将字节加密为字节,并且希望能够处理常规文件,那么唯一可能resultmod。如果选择较小的一个,则必须至少有一对输入字节映射到相同的密文。另一方面,如果选择较大的256,则无法将结果值范围1:1映射到类型mod的范围内。此外,您必须确定选择byte相对于256的素数,但这很容易:因为256是2的幂,任何奇数键都可以。只要选择这样一个键,256个连续整数的任何范围内的两个输入值都不会映射到相同的结果。