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 |