এই স্কিমে (Playfair cipher), একক অক্ষরের বদলে অক্ষর যুগল (pairs of letters) এনক্রিপ্ট করা হয়।
প্লেফেয়ার সাইফারে প্রথমে একটি কী টেবিল (key table) তৈরি করা হয়। কী টেবিল হলো ৫x৫ গ্রিড (grid) যা প্লেইনটেক্সট এনক্রিপ্ট করার কী হিসেবে কাজ করে। ২৫টি অক্ষর ইউনিক (unique) হতে হবে এবং অ্যালফাবেটের একটি অক্ষর (সাধারণত J) বাদ দেওয়া হয়। যদি প্লেইনটেক্সটে J থাকে, তবে সেটি I দিয়ে রিপ্লেস করা হয়।
সেন্ডার (sender) এবং রিসিভার (receiver) একটি নির্দিষ্ট কী নির্ধারণ করে, যেমন 'tutorials'। কী টেবিলে বাম থেকে ডান যেতে যেতে প্রথম ক্যারেক্টারগুলো (ডুপ্লিকেট বাদে) কী ফ্রেজ (phrase) হয়। বাকি অংশ アルফাবেটিক ক্রমে বাকি অক্ষরগুলো দিয়ে ভরা হয়।

প্লেফেয়ার সাইফারের প্রসেস (Process of Playfair Cipher)
প্রথমে প্লেইনটেক্সট মেসেজকে দুটি অক্ষরের যুগলে (digraphs) ভাগ করা হয়। অক্ষর সংখ্যা বিজোড় হলে শেষে Z যোগ করা হয়। উদাহরণস্বরূপ, "hide money" এনক্রিপ্ট করতে চাইলে:
HI DE MO NE YZ
এনক্রিপশনের নিয়মগুলো:
- নियम ১: যদি দুটি অক্ষর একই কলামে থাকে, তবে প্রতিটির নিচের অক্ষর নেওয়া হয় (নিচে না থাকলে উপরে ঘুরে আসা)। 'H' এবং 'I' একই কলামে, তাই নিচের অক্ষরগুলো নেওয়া হয়। HI → QC

- নियम ২: যদি দুটি অক্ষর একই রোতে থাকে, তবে প্রতিটির ডানের অক্ষর নেওয়া হয় (ডানে না থাকলে বামে ঘুরে আসা)। 'D' এবং 'E' একই রোতে, তাই ডানের অক্ষরগুলো নেওয়া হয়। DE → EF

- নियम ৩: যদি উপরের দুটি নিয়মে কোনোটিই সত্য না হয়, তবে দুটি অক্ষর দিয়ে একটি রেক্ট্যাঙ্গল (rectangle) বানানো হয় এবং রেক্ট্যাঙ্গলের আড়াল কোণে (horizontal opposite corner) থাকা অক্ষরগুলো নেওয়া হয়।

এই নিয়মগুলো ব্যবহার করে 'tutorials' কী দিয়ে 'hide money' এনক্রিপ্ট করলে ফলাফল:
QC EF NU MF ZV
প্লেফেয়ার সাইফার ডিক্রিপ্ট করা এনক্রিপশনের রিভার্স প্রসেস। রিসিভারের কাছে একই কী থাকে, তাই সে একই কী টেবিল বানাতে পারে এবং সেই কী দিয়ে এনক্রিপ্ট করা মেসেজ ডিক্রিপ্ট করতে পারে।
নিচে প্লেফেয়ার সাইফার ব্যবহার করে মেসেজ ডিকোড করার 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) ) {
// একই রো (same row)
if( j == p ) {
nmsg+= getChar( j, k + dir );
nmsg += getChar( p, q + dir );
}
// একই কলাম (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() {
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 ) {
return n[ (b + 5) % 5 ][ (a + 5) % 5 ];
}
bool getPos( char l, int &c, int &d ) {
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 ) {
for( string::iterator it = t.begin(); it != t.end(); it++ ) {
*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 ) {
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 ) == string::npos ) s += *it;
}
copy( s.begin(), s.end(), &n[0][0] );
}
};
int main( int argc, char* argv[] ) {
string k, i, msg;
bool m, c;
cout << "Encrypt or Decrypt? ";
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 0;
}
আউটপুট
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