【问题标题】:Inverting matrices mod-26 with Eigen C++ library使用 Eigen C++ 库反转矩阵 mod-26
【发布时间】:2013-12-04 11:27:59
【问题描述】:

我正在尝试编写一个程序来破解 C++ 中任意维度 (MxM) 的希尔密码。部分过程需要我计算矩阵的 mod-26 逆。

例如,2x2 数组的模逆

14 3 11 0

是

0 19 9 24

我有一个函数可以仅对 2x2 数组完成此操作,这还不够。我知道在大维数组上计算逆很困难,所以我使用的是 Eigen C++ 库。但是,Eigen inverse() 函数将其作为上述矩阵的逆矩阵:

0.000 0.091 0.333 -0.424

如何计算具有 Eigen 的任意维度矩阵所需的模 26 逆?

【问题讨论】:

    标签: c++ cryptography eigen modulus


    【解决方案1】:

    试试这个:

    #include <iostream>
    #include <functional>
    #include <Eigen/Dense>
    
    using namespace Eigen;                                                                                       
    using namespace std;                                                                                         
    
    int inverse_mod_26(int d)                                                                                    
    {                                                                                                            
       // We're not going to use Euclidean Alg. or                                                               
       // even Fermat's Little Theorem, but brute force                                                          
       int base = 26, inv = 1;                                                                                   
    
       while ( (inv < base) &&                                                                                   
           (((d * ++inv) % 26) != 1)) {}                                                                         
    
       return inv;                                                                                               
    }                                                                                                            
    
    int main(int argc, char **argv)                                                                              
    {                                                                                                            
    
       Matrix2d m, minv;                                                                                         
       int inv_factor;                                                                                           
       m << 14, 3, 15, 0;                                                                                        
       double mdet = m.determinant();                                                                            
    
       minv = mdet * m.inverse();                                                                                
       transform(&minv.data()[0], &minv.data()[4], &minv.data()[0],                                              
             [](double d){ return static_cast<int>(d) % 26;});                                                   
       if ((static_cast<int>(mdet) % 26) == 1) { // no further modification}                                     
       else                                       
         {                                                                                                       
            inv_factor = inverse_mod_26(std::abs((m * minv)(0,0)));                                              
            if (inv_factor == 26)                                                                                
              {                                                                                                  
                 cerr << "No inverse exists!" << endl;                                                           
                 return EXIT_FAILURE;                                                                            
              }                                                                                                  
    
            transform(&minv.data()[0], &minv.data()[4], &minv.data()[0],                                         
                  [=](double d){ return static_cast<int>(d) * inv_factor;});                                     
         }                                                                                                       
    
       cout << "m = " << endl << m << endl;                                                                      
       cout << "minv = " << endl << minv << endl;                                                                
       cout << "(m * minv) = " << endl << m * minv << endl;                                                      
    
       return 0;                                                                                                 
    }                            
    

    这是一个 2x2 的情况,以 26 为基数,但可以轻松修改。该算法依赖于修改正常矩阵逆,如果您愿意,可以很容易地解释。如果您的原始矩阵具有与 26 不互质的行列式(在正常意义上);即,如果GCD(det(m), 26) != 1,那么它不会有逆。

    提示:为了避免这个问题以及上面的 else 子句,用三个任意字符填充您的字典,将大小设置为 29,这是素数,并且可以轻松满足上面的 GCD 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多