使用Playfair密码加密消息的C++程序
在这种方案中,加密的是字母对,而不是像简单替换密码那样加密单个字母。
在Playfair密码中,首先创建一个密钥表。密钥表是一个5×5的字母网格,用作加密明文的密钥。所有25个字母必须是唯一的,并且其中一个字母(通常是J)会被省略,因为我们只需要25个字母而不是26个。如果明文中包含J,则将其替换为I。
发送方和接收方决定一个特定的密钥,例如“tutorials”。在密钥表中,表中的第一个字符(从左到右)是该短语,不包括重复的字母。表的其余部分将填充剩余的字母表字母,按自然顺序排列。密钥表如下所示:-

Playfair密码的过程
首先,将明文消息拆分为两个字母的字母对(二元组)。如果字母数为奇数,则在最后一个字母后添加一个Z。假设我们要加密消息“hide money”。它将被写成:-
HI DE MO NE YZ
加密规则如下:-
- 如果两个字母都在同一列中,取每个字母下面的字母(如果在底部则回到顶部)“H”和“I”在同一列中,因此取它们下面的字母进行替换。HI → QC

- 如果两个字母都在同一行中,取每个字母右边的字母(如果在最右边则回到左边)“D”和“E”在同一行中,因此取它们右边的字母进行替换。DE → EF

- 如果上述两个规则都不适用,则用这两个字母形成一个矩形,并取矩形水平对角上的字母。

使用这些规则,“hide money”使用密钥“tutorials”加密的结果将是:-
QC EF NU MF ZV
Playfair密码的解密过程与加密过程相同,只是反过来。接收方拥有相同的密钥,可以创建相同的密钥表,然后解密使用该密钥创建的任何消息。
这里给出了一个使用Playfair密码加密消息的C++程序。
算法
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
示例
#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" );
}输出
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
广告
数据结构
网络
RDBMS
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP