Computer >> Máy Tính >  >> Lập trình >> C ++

Chương trình C ++ để giải mã một tin nhắn được mã hóa bằng Playfair Cipher

Trong sơ đồ này, các cặp chữ cái được mã hóa, thay vì các chữ cái đơn lẻ như trong trường hợp mật mã thay thế đơn giản.

Trong mật mã playfair, ban đầu một bảng khóa được tạo. Bảng khóa là một lưới bảng chữ cái 5 × 5 đóng vai trò là khóa để mã hóa bản rõ. Mỗi bảng trong số 25 bảng chữ cái phải là duy nhất và một chữ cái của bảng chữ cái (thường là J) bị bỏ qua khỏi bảng vì chúng ta chỉ cần 25 bảng chữ cái thay vì 26. Nếu bản rõ chứa J, thì nó được thay thế bằng I.

Người gửi và người nhận tin tưởng vào một khóa cụ thể, chẳng hạn như "hướng dẫn". Trong bảng khóa, các ký tự đầu tiên (đi từ trái sang phải) trong bảng là cụm từ, loại trừ các ký tự trùng lặp. Phần còn lại của bảng sẽ được điền bằng các chữ cái còn lại của bảng chữ cái, theo thứ tự tự nhiên. Bảng chính hoạt động -

Chương trình C ++ để giải mã một tin nhắn được mã hóa bằng Playfair Cipher

Quy trình tạo mật mã Playfair

Đầu tiên, một thông điệp rõ ràng được chia thành các cặp gồm hai chữ cái (digraph). Nếu có một số lẻ các chữ cái, một Z được thêm vào chữ cái cuối cùng. Chúng ta hãy xem xét điều đó, chúng ta muốn mã hóa thông điệp “giấu tiền”. Nó sẽ được viết là -

HI DE MO NE YZ

Các quy tắc mã hóa là -

  • Nếu cả hai chữ cái nằm trong cùng một cột, hãy lấy chữ cái bên dưới mỗi chữ cái (quay trở lại trên cùng nếu ở dưới cùng) ‘H’ và ‘I’ ở cùng một cột, do đó hãy lấy chữ cái bên dưới chúng để thay thế. HI → QC

Chương trình C ++ để giải mã một tin nhắn được mã hóa bằng Playfair Cipher

  • Nếu cả hai chữ cái ở cùng một hàng, hãy lấy chữ cái ở bên phải của mỗi chữ cái (quay trở lại bên trái nếu ở xa nhất bên phải) 'D' và 'E' ở cùng một hàng, do đó hãy lấy chữ cái ở bên phải của chúng thay thế. DE → EF

Chương trình C ++ để giải mã một tin nhắn được mã hóa bằng Playfair Cipher

  • Nếu cả hai quy tắc trên đều không đúng, hãy tạo một hình chữ nhật có hai chữ cái và lấy các chữ cái ở góc đối diện theo chiều ngang của hình chữ nhật đó.

Chương trình C ++ để giải mã một tin nhắn được mã hóa bằng Playfair Cipher

Sử dụng các quy tắc này, kết quả của việc mã hóa 'giấu tiền' với khóa 'hướng dẫn' sẽ là -

QC EF NU MF ZV

Việc giải mã mật mã Playfair cũng đơn giản như thực hiện ngược lại quy trình tương tự. Người nhận có cùng một khóa và có thể tạo cùng một bảng khóa, sau đó giải mã bất kỳ thông báo nào được thực hiện bằng khóa đó.

Đây là một chương trình C ++ được cung cấp để mã hóa một tin nhắn bằng Playfair Cipher.

Thuật toán

Begin
Function void play( int dir )
For it = msg.begin() to it != msg.end()
   If ( getPos( *it++, j, k ) )
      If ( getPos( *it, p, q) )
         If ( j == p )
            nmsg+= getChar( j, k + dir )
            nmsg += getChar( p, q + dir )
         else if( k == q )
            nmsg += getChar( j + dir, k )
            nmsg += getChar( p + dir, q )
         else
            nmsg += getChar( p, k )
            nmsg += getChar( j, q )
         done
      done
   done
   msg = nmsg
done
End

Ví dụ

#include <iostream>
#include <string>
using namespace std;
class playfair {
   public:
      string msg; char n[5][5];
   void play( string k, string t, bool m, bool e ) {
      createEncoder( k, m );
      getText( t, m, e );
      if( e )
         play( 1 );
      else
         play( -1 );
      print();
   }
   private:
   void play( int dir ) {
      int j,k,p,q;
      string nmsg;
      for( string::const_iterator it = msg.begin(); it != msg.end(); it++ ) {
         if( getPos( *it++, j, k ) )
         if( getPos( *it, p, q) ) {
            //for same row
            if( j == p ) {
               nmsg+= getChar( j, k + dir );
               nmsg += getChar( p, q + dir );
            }
            //for same column
            else if( k == q ) {
               nmsg += getChar( j + dir, k );
               nmsg += getChar( p + dir, q );
            } else {
               nmsg += getChar( p, k );
               nmsg += getChar( j, q );
            }
         }
      }
      msg = nmsg;
   }
   void print() //print the solution {
      cout << "\n\n Solution:" << endl;
      string::iterator it = msg.begin(); int count = 0;
      while( it != msg.end() ) {
         cout << *it;
         it++;
         cout << *it << " ";
         it++;
         if( ++count >= 26 )
         cout << endl;
         count = 0;
      }
      cout << endl << endl;
   }
   char getChar( int a, int b ) { //get the characters
      return n[ (b + 5) % 5 ][ (a + 5) % 5 ];
   }
   bool getPos( char l, int &c, int &d ) { //get the position
      for( int y = 0; y < 5; y++ )
         for( int x = 0; x < 5; x++ )
            if( n[y][x] == l ) {
               c = x;
               d= y;
               return true;
            }
      return false;
   }
   void getText( string t, bool m, bool e ) { //get the original message
      for( string::iterator it = t.begin(); it != t.end(); it++ ) {
         //to choose J = I or no Q in the alphabet.
         *it = toupper( *it );
         if( *it < 65 || *it > 90 )
            continue;
         if( *it == 'J' && m )
            *it = 'I';
         else if( *it == 'Q' && !m )
            continue;
         msg += *it;
      } if( e ) {
         string nmsg = ""; size_t len = msg.length();
         for( size_t x = 0; x < len; x += 2 ) {
            nmsg += msg[x];
            if( x + 1 < len ) {
               if( msg[x] == msg[x + 1] ) nmsg += 'X';
               nmsg += msg[x + 1];
            }
         }
         msg = nmsg;
      }
      if( msg.length() & 1 )
      msg += 'X';
   }
   void createEncoder( string key, bool m ) { //creation of the key table
      if( key.length() < 1 )
      key= "KEYWORD";
      key += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      string s= "";
      for( string::iterator it = key.begin(); it != key.end(); it++ ) {
         *it = toupper( *it );
         if( *it < 65 || *it > 90 )
            continue;
         if( ( *it == 'J' && m ) || ( *it == 'Q' && !m ) )
            continue;
         if( s.find( *it ) == -1 )
            s += *it;
      }
      copy( s.begin(), s.end(), &n[0][0] );
   }
};
int main( int argc, char* argv[] ) {
   string k, i, msg;
   bool m, c;
   cout << "Encrpty or Decypt? ";
   getline( cin, i );
   c = ( i[0] == 'e' || i[0] == 'E' );
   cout << "Enter a key: ";
   getline( cin, k);
   cout << "I <-> J (Y/N): ";
   getline( cin, i );
   m = ( i[0] == 'y' || i[0] == 'Y' );
   cout << "Enter the message: ";
   getline( cin, msg );
   playfair pf;
   pf.play( k, msg,m, c );
   return system( "pause" );
}

Đầu ra

Encrpty or Decypt? d
Enter a key: players
I <-> J (Y/N): y
Enter the message: OK GC GC MZ MQ CF YA RL QH OM

Solution:
TH IS IS TU TO RI AL SP OI NT