Playfair cipher: Difference between revisions
No edit summary |
m (→{{header|C++}}) |
||
Line 8: | Line 8: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
<lang cpp> |
<lang cpp>#include <iostream> |
||
#include <iostream> |
|||
#include <string> |
#include <string> |
||
//-------------------------------------------------------------------------------------------------- |
|||
using namespace std; |
using namespace std; |
||
//-------------------------------------------------------------------------------------------------- |
|||
class playfair |
class playfair |
||
{ |
{ |
||
Line 30: | Line 27: | ||
{ |
{ |
||
int a, b, c, d; string ntxt; |
int a, b, c, d; string ntxt; |
||
for( string:: |
for( string::const_iterator ti = _txt.begin(); ti != _txt.end(); ti++ ) |
||
{ |
{ |
||
if( getCharPos |
if( getCharPos( *ti++, a, b ) ) |
||
if( getCharPos |
if( getCharPos( *ti, c, d ) ) |
||
{ |
{ |
||
if( a == c ) { ntxt |
if( a == c ) { ntxt += getChar( a, b + dir ); ntxt += getChar( c, d + dir ); } |
||
else if( b == d ){ ntxt |
else if( b == d ){ ntxt += getChar( a + dir, b ); ntxt += getChar( c + dir, d ); } |
||
else { ntxt |
else { ntxt += getChar( c, b ); ntxt += getChar( a, d ); } |
||
} |
} |
||
} |
} |
||
Line 49: | Line 46: | ||
while( si != _txt.end() ) |
while( si != _txt.end() ) |
||
{ |
{ |
||
cout << |
cout << *si; si++; cout << *si << " "; si++; |
||
if( ++cnt >= 26 ) cout << endl, cnt = 0; |
if( ++cnt >= 26 ) cout << endl, cnt = 0; |
||
} |
} |
||
Line 55: | Line 52: | ||
} |
} |
||
char |
char getChar( int a, int b ) |
||
{ |
{ |
||
⚫ | |||
if( a > 4 ) a = 0; if( b > 4 ) b = 0; |
|||
if( a < 0 ) a = 4; if( b < 0 ) b = 4; |
|||
⚫ | |||
} |
} |
||
Line 65: | Line 60: | ||
{ |
{ |
||
for( int y = 0; y < 5; y++ ) |
for( int y = 0; y < 5; y++ ) |
||
{ |
|||
int yy = 5 * y; |
|||
for( int x = 0; x < 5; x++ ) |
for( int x = 0; x < 5; x++ ) |
||
if( _m[x |
if( _m[y][x] == l ) |
||
{ a = x; b = y; return true; } |
{ a = x; b = y; return true; } |
||
} |
|||
return false; |
return false; |
||
} |
} |
||
Line 79: | Line 71: | ||
for( string::iterator si = t.begin(); si != t.end(); si++ ) |
for( string::iterator si = t.begin(); si != t.end(); si++ ) |
||
{ |
{ |
||
*si = toupper( *si ); if( *si < 65 || *si > 90 ) continue; |
|||
if |
if( *si == 'J' && ij ) *si = 'I'; |
||
else if |
else if( *si == 'Q' && !ij ) continue; |
||
_txt |
_txt += *si; |
||
} |
} |
||
if( e ) |
if( e ) |
||
Line 89: | Line 81: | ||
for( size_t x = 0; x < len; x += 2 ) |
for( size_t x = 0; x < len; x += 2 ) |
||
{ |
{ |
||
ntxt |
ntxt += _txt[x]; |
||
if( x + 1 < len ) |
if( x + 1 < len ) |
||
{ |
{ |
||
if( _txt[x] == _txt[x + 1] ) ntxt |
if( _txt[x] == _txt[x + 1] ) ntxt += 'X'; |
||
ntxt |
ntxt += _txt[x + 1]; |
||
} |
} |
||
} |
} |
||
_txt = ntxt; |
_txt = ntxt; |
||
} |
} |
||
if( _txt.length() & 1 ) _txt |
if( _txt.length() & 1 ) _txt += 'X'; |
||
} |
} |
||
Line 104: | Line 96: | ||
{ |
{ |
||
if( k.length() < 1 ) k = "KEYWORD"; |
if( k.length() < 1 ) k = "KEYWORD"; |
||
k |
k += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string nk = ""; |
||
for( string::iterator si = k.begin(); si != k.end(); si++ ) |
for( string::iterator si = k.begin(); si != k.end(); si++ ) |
||
{ |
{ |
||
*si = toupper( *si ); if( *si < 65 || *si > 90 ) continue; |
|||
if |
if( ( *si == 'J' && ij ) || ( *si == 'Q' && !ij ) )continue; |
||
if( nk.find |
if( nk.find( *si ) == -1 ) nk += *si; |
||
} |
} |
||
copy( nk.begin(), nk.end(), _m ); |
copy( nk.begin(), nk.end(), &_m[0][0] ); |
||
} |
} |
||
string _txt; char _m[ |
string _txt; char _m[5][5]; |
||
}; |
}; |
||
//-------------------------------------------------------------------------------------------------- |
|||
int main( int argc, char* argv[] ) |
int main( int argc, char* argv[] ) |
||
{ |
{ |
||
Line 125: | Line 117: | ||
cout << "Enter the text: "; getline( cin, txt ); |
cout << "Enter the text: "; getline( cin, txt ); |
||
playfair pf; pf.doIt( key, txt, ij, e ); return system( "pause" ); |
playfair pf; pf.doIt( key, txt, ij, e ); return system( "pause" ); |
||
⚫ | |||
} |
|||
//-------------------------------------------------------------------------------------------------- |
|||
⚫ | |||
{{out}}<pre> |
{{out}}<pre> |
||
(E)ncode or (D)ecode? e |
(E)ncode or (D)ecode? e |
Revision as of 08:12, 19 May 2013
Implement a Playfair cipher encryption and decryption.
The user must be able to choose J = I or no Q in the alphabet. The output of the encrypted and decrypted message must be in capitalized digraphs, separated by spaces.
Output example: HI DE TH EG OL DI NT HE TR EX ES TU MP.
C++
<lang cpp>#include <iostream>
- include <string>
using namespace std;
class playfair { public:
void doIt( string k, string t, bool ij, bool e ) {
createGrid( k, ij ); getTextReady( t, ij, e ); if( e ) doIt( 1 ); else doIt( -1 ); display();
}
private:
void doIt( int dir ) {
int a, b, c, d; string ntxt; for( string::const_iterator ti = _txt.begin(); ti != _txt.end(); ti++ ) { if( getCharPos( *ti++, a, b ) ) if( getCharPos( *ti, c, d ) ) { if( a == c ) { ntxt += getChar( a, b + dir ); ntxt += getChar( c, d + dir ); } else if( b == d ){ ntxt += getChar( a + dir, b ); ntxt += getChar( c + dir, d ); } else { ntxt += getChar( c, b ); ntxt += getChar( a, d ); } } } _txt = ntxt;
}
void display() {
cout << "\n\n OUTPUT:\n=========" << endl; string::iterator si = _txt.begin(); int cnt = 0; while( si != _txt.end() ) { cout << *si; si++; cout << *si << " "; si++; if( ++cnt >= 26 ) cout << endl, cnt = 0; } cout << endl << endl;
}
char getChar( int a, int b ) {
return _m[b % 5][a % 5];
}
bool getCharPos( char l, int &a, int &b ) {
for( int y = 0; y < 5; y++ ) for( int x = 0; x < 5; x++ ) if( _m[y][x] == l ) { a = x; b = y; return true; }
return false;
}
void getTextReady( string t, bool ij, bool e ) {
for( string::iterator si = t.begin(); si != t.end(); si++ ) { *si = toupper( *si ); if( *si < 65 || *si > 90 ) continue; if( *si == 'J' && ij ) *si = 'I'; else if( *si == 'Q' && !ij ) continue; _txt += *si; } if( e ) { string ntxt = ""; size_t len = _txt.length(); for( size_t x = 0; x < len; x += 2 ) { ntxt += _txt[x]; if( x + 1 < len ) { if( _txt[x] == _txt[x + 1] ) ntxt += 'X'; ntxt += _txt[x + 1]; } } _txt = ntxt; } if( _txt.length() & 1 ) _txt += 'X';
}
void createGrid( string k, bool ij ) {
if( k.length() < 1 ) k = "KEYWORD"; k += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string nk = ""; for( string::iterator si = k.begin(); si != k.end(); si++ ) { *si = toupper( *si ); if( *si < 65 || *si > 90 ) continue; if( ( *si == 'J' && ij ) || ( *si == 'Q' && !ij ) )continue; if( nk.find( *si ) == -1 ) nk += *si; } copy( nk.begin(), nk.end(), &_m[0][0] );
}
string _txt; char _m[5][5];
};
int main( int argc, char* argv[] ) {
string key, i, txt; bool ij, e; cout << "(E)ncode or (D)ecode? "; getline( cin, i ); e = ( i[0] == 'e' || i[0] == 'E' ); cout << "Enter a en/decryption key: "; getline( cin, key ); cout << "I <-> J (Y/N): "; getline( cin, i ); ij = ( i[0] == 'y' || i[0] == 'Y' ); cout << "Enter the text: "; getline( cin, txt ); playfair pf; pf.doIt( key, txt, ij, e ); return system( "pause" );
}</lang>
- Output:
(E)ncode or (D)ecode? e Enter a en/decryption key: playfair example I <-> J (Y/N): y Enter the text: Hide the gold in the tree stump
OUTPUT: ========= BM OD ZB XD NA BE KU DM UI XM MO UV IF
(E)ncode or (D)ecode? d Enter a en/decryption key: playfair example I <-> J (Y/N): y Enter the text: BMODZBXDNABEKUDMUIXMMOUVIFOUTPUT: ========= HI DE TH EG OL DI NT HE TR EX ES TU MP
Perl 6
<lang perl6># Instantiate a specific encoder/decoder.
sub playfair( $key,
$from = 'J',
$to = $from eq 'J' ?? 'I' !! ) {
sub canon($str) { $str.subst(/<-alpha>/,, :g).uc.subst(/$from/,$to,:g) }
# Build 5x5 matrix. my @m = canon($key ~ ('A'..'Z').join).comb.uniq.map:
-> $a,$b,$c,$d,$e { [$a,$b,$c,$d,$e] }
# Pregenerate all forward translations. my %ENC = gather {
# Map pairs in same row. for @m -> @r { for ^@r X ^@r -> \i,\j { next if i == j; take @r[i] ~ @r[j] => @r[(i+1)%5] ~ @r[(j+1)%5]; } }
# Map pairs in same column. for ^5 -> $c { my @c = @m.map: *.[$c]; for ^@c X ^@c -> \i,\j { next if i == j; take @c[i] ~ @c[j] => @c[(i+1)%5] ~ @c[(j+1)%5]; } }
# Map pairs with cross-connections. for ^5 X ^5 X ^5 X ^5 -> \i1,\j1,\i2,\j2 { next if i1 == i2 or j1 == j2; take @m[i1][j1] ~ @m[i2][j2] => @m[i1][j2] ~ @m[i2][j1]; }
}
# Generate reverse translations. my %DEC = %ENC.invert;
return
anon sub enc($red) { my @list = canon($red).comb(/(.) (.?) <?{ $1 ne $0 }>/); ~@list.map: { .chars == 1 ?? %ENC{$_~'X'} !! %ENC{$_} } }, anon sub dec($black) { my @list = canon($black).comb(/../); ~@list.map: { %DEC{$_} } } }
my (&encode,&decode) = playfair 'Playfair example';
my $orig = "Hide the gold in...the TREESTUMP!!!"; say " orig:\t$orig";
my $black = encode $orig; say "black:\t$black";
my $red = decode $black; say " red:\t$red";</lang>
- Output:
orig: Hide the gold in...the TREESTUMP!!! black: BM OD ZB XD NA BE KU DM UI XM MO UV IF red: HI DE TH EG OL DI NT HE TR EX ES TU MP