ในรูปแบบนี้ ตัวอักษรคู่จะถูกเข้ารหัส แทนที่จะเป็นตัวอักษรเดี่ยว เช่นในกรณีของการเข้ารหัสแบบแทนที่อย่างง่าย
ในรหัส playfair ในขั้นต้นจะมีการสร้างตารางคีย์ ตารางคีย์คือตารางตัวอักษรขนาด 5×5 ซึ่งทำหน้าที่เป็นคีย์สำหรับเข้ารหัสข้อความธรรมดา ตัวอักษรทั้ง 25 ตัวต้องไม่ซ้ำกัน และตัวอักษรหนึ่งตัว (โดยปกติคือ J) จะถูกละเว้นจากตาราง เนื่องจากเราต้องการเพียง 25 ตัวอักษรแทนที่จะเป็น 26 ตัว หากข้อความธรรมดามี J ระบบจะแทนที่ด้วย I
ผู้ส่งและผู้รับเสียชีวิตในคีย์ใดคีย์หนึ่ง ให้พูดว่า 'บทช่วยสอน' ในตารางคีย์ อักขระตัวแรก (จากซ้ายไปขวา) ในตารางคือวลี ไม่รวมตัวอักษรที่ซ้ำกัน ส่วนที่เหลือของตารางจะเต็มไปด้วยตัวอักษรที่เหลือของตัวอักษรในลำดับที่เป็นธรรมชาติ ตารางคีย์ได้ผลเป็น −
ขั้นตอนของ Playfair Cipher
ขั้นแรก ข้อความธรรมดาจะแบ่งออกเป็นคู่ของตัวอักษรสองตัว (ไดกราฟ) หากมีตัวอักษรเป็นจำนวนคี่ ให้เติม Z ลงในตัวอักษรตัวสุดท้าย ให้เราพิจารณาว่า เราต้องการเข้ารหัสข้อความ “ซ่อนเงิน” โดยจะเขียนเป็น −
HI DE MO NE YZ
กฎของการเข้ารหัสคือ −
-
หากตัวอักษรทั้งสองอยู่ในคอลัมน์เดียวกัน ให้นำตัวอักษรที่อยู่ด้านล่างแต่ละรายการ (กลับไปด้านบนหากอยู่ด้านล่าง) 'H' และ 'I' อยู่ในคอลัมน์เดียวกัน ดังนั้นให้นำตัวอักษรที่อยู่ด้านล่างมาแทนที่ HI → QC
-
หากตัวอักษรสองตัวอยู่ในแถวเดียวกัน ให้เอาตัวอักษรที่อยู่ทางขวาของแต่ละตัว (ให้กลับไปทางซ้ายถ้าอยู่ขวาสุดทางขวาสุด) 'D' และ 'E' อยู่ในแถวเดียวกัน ให้เอาตัวอักษรไปทางขวา จะเข้ามาแทนที่. DE → EF
-
ถ้ากฎสองข้อก่อนหน้านี้ไม่เป็นความจริง ให้สร้างสี่เหลี่ยมผืนผ้าด้วยตัวอักษรสองตัวและนำตัวอักษรที่มุมตรงข้ามแนวนอนของสี่เหลี่ยมผืนผ้า
เมื่อใช้กฎเหล่านี้ ผลลัพธ์ของการเข้ารหัส 'ซ่อนเงิน' ด้วยคีย์ของ 'บทช่วยสอน' จะเป็น -
QC EF NU MF ZV
การถอดรหัสรหัส Playfair นั้นง่ายพอๆ กับการทำกระบวนการแบบย้อนกลับ ผู้รับมีคีย์เดียวกันและสามารถสร้างตารางคีย์เดียวกันได้ จากนั้นถอดรหัสข้อความใดๆ ที่สร้างโดยใช้คีย์นั้น
นี่คือโปรแกรม C++ สำหรับเข้ารหัสข้อความโดยใช้ Playfair Cipher
อัลกอริทึม
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? 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