C++程序使用Playfair密码对消息进行编码

C++ Program to Encode a Message Using Playfair Cipher

在这种方案中,对字母进行加密,而不是像简单替换密码那样对单个字母进行加密。

在公平游戏密码中,最初会创建一个密钥表。密钥表是一个5×5的字母网格,用作加密明文的密钥。 25个字母中的每个字母必须唯一,并且表中省略了一个字母(通常为J),因为我们仅需要25个字母而不是26个字母。如果明文包含J,则将其替换为I。

发送者和接收者都在使用特定的密钥(例如"教程")。在密钥表中,表中的第一个字符(从左到右)是短语,不包括重复的字母。表格的其余部分将以自然顺序填充剩余的字母。密钥表的计算结果是-

Playfair密码的过程

首先,将明文消息分成两个字母(图)对。如果字母的数量为奇数,则将Z添加到最后一个字母。让我们考虑一下,我们想对消息"隐藏金钱"进行加密。它将写为-

1
HI DE MO NE YZ

加密规则为-

  • 如果两个字母都在同一列中,则将每个字母下方的字母(如果在底部,则返回顶部)" H"和" I"在同一列中,因此将其下方的字母替换。 HI→QC

  • 如果两个字母都在同一行中,请在每个字母的右边加上字母(如果最右边,则返回左侧)'D'和'E'在同一行中,因此在它们的右边加上字母取代。 DE→EF

  • 如果前两个规则都不成立,则用两个字母组成一个矩形,并在矩形的水平相对角上取字母。

使用这些规则,使用"教程"密钥对"隐藏金钱"进行加密的结果将是-

1
QC EF NU MF ZV

解密Playfair密码与执行相反的过程一样简单。接收方具有相同的密钥,可以创建相同的密钥表,然后解密使用该密钥发出的任何消息。

这是一个C ++程序,用于使用Playfair Cipher编码消息。

演算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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 <<"

 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" );
}

输出量

1
2
3
4
5
6
7
8
Encrpty or Decypt? e
Enter a key: players
I <-> J (Y/N): y
Enter the message: This is tutorialspoint


Solution:
OK GC GC MZ MQ CF YA RL QH OM