我已经阅读了很多关于这个主题的内容,关于欧几里德算法,我在这里有所需的所有参考资料:
(我的问题的最佳来源) - > 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;
}
答案 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密码的精神(即使用多字节密钥)执行此操作,则会将预先计算解码表所需的输入长度乘以获胜。
但请注意,使用您描述的函数来定义可行的密码取决于每个有效的输入值,从而产生不同的结果。但是,正如我们已经讨论过的,x
和key
的某些组合会产生重复的结果。此外,如果可能结果值的空间与可能输入值的空间大小相同,则必须选择mod
和key
的组合,这会导致所有可能的mod
值正在使用,否则你无法避免重复。
如果要将字节加密为字节,并且希望能够处理常规文件,那么唯一可能result
为mod
。如果选择较小的一个,则必须至少有一对输入字节映射到相同的密文。另一方面,如果选择较大的256
,则无法将结果值范围1:1映射到类型mod
的范围内。此外,您必须确定选择byte
相对于256的素数,但这很容易:因为256是2的幂,任何奇数键都可以。只要选择这样一个键,256个连续整数的任何范围内的两个输入值都不会映射到相同的结果。