Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Playfair-cipher/00-META.yaml
Normal file
4
Task/Playfair-cipher/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Encryption
|
||||
from: http://rosettacode.org/wiki/Playfair_cipher
|
||||
13
Task/Playfair-cipher/00-TASK.txt
Normal file
13
Task/Playfair-cipher/00-TASK.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
;Task:
|
||||
Implement a [[wp: Playfair cipher| Playfair cipher]] for 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
|
||||
<br><br>
|
||||
|
||||
60
Task/Playfair-cipher/11l/playfair-cipher.11l
Normal file
60
Task/Playfair-cipher/11l/playfair-cipher.11l
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
F uniq(seq)
|
||||
[Char] seen
|
||||
L(x) seq
|
||||
I x !C seen
|
||||
seen.append(x)
|
||||
R seen
|
||||
|
||||
F partition(seq, n)
|
||||
R (0 .< seq.len).step(n).map(i -> @seq[i .< i + @n])
|
||||
|
||||
F canonicalize(s)
|
||||
R s.uppercase().filter(c -> c.is_uppercase()).join(‘’).replace(‘J’, ‘I’)
|
||||
|
||||
T Playfair
|
||||
[String = String] dec, enc
|
||||
|
||||
F (key)
|
||||
V m = partition(uniq(canonicalize(key‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)), 5)
|
||||
|
||||
L(row) m
|
||||
L(i, j) cart_product(0.<5, 0.<5)
|
||||
I i != j
|
||||
.enc[row[i]‘’row[j]] = row[(i + 1) % 5]‘’row[(j + 1) % 5]
|
||||
|
||||
L(ci) 5
|
||||
V c = [m[0][ci], m[1][ci], m[2][ci], m[3][ci], m[4][ci]]
|
||||
L(i, j) cart_product(0.<5, 0.<5)
|
||||
I i != j
|
||||
.enc[c[i]‘’c[j]] = c[(i + 1) % 5]‘’c[(j + 1) % 5]
|
||||
|
||||
L(i1, j1, i2, j2) cart_product(0.<5, 0.<5, 0.<5, 0.<5)
|
||||
I i1 != i2 & j1 != j2
|
||||
.enc[m[i1][j1]‘’m[i2][j2]] = m[i1][j2]‘’m[i2][j1]
|
||||
|
||||
.dec = Dict(.enc.map((k, v) -> (v, k)))
|
||||
|
||||
F encode(txt)
|
||||
V c = canonicalize(txt)
|
||||
[String] lst
|
||||
V i = 0
|
||||
L i < c.len - 1
|
||||
I c[i + 1] == c[i]
|
||||
lst [+]= c[i]‘X’
|
||||
i++
|
||||
E
|
||||
lst [+]= c[i]‘’c[i + 1]
|
||||
i += 2
|
||||
I i == c.len - 1
|
||||
lst [+]= c.last‘X’
|
||||
R lst.map(a -> @.enc[a]).join(‘ ’)
|
||||
|
||||
F decode(encoded)
|
||||
R partition(canonicalize(encoded), 2).map(p -> @.dec[p]).join(‘ ’)
|
||||
|
||||
V playfair = Playfair(‘Playfair example’)
|
||||
V orig = ‘Hide the gold in...the TREESTUMP!!!’
|
||||
print(‘Original: ’orig)
|
||||
V enc = playfair.encode(orig)
|
||||
print(‘Encoded: ’enc)
|
||||
print(‘Decoded: ’playfair.decode(enc))
|
||||
77
Task/Playfair-cipher/APL/playfair-cipher.apl
Normal file
77
Task/Playfair-cipher/APL/playfair-cipher.apl
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
⍝⍝⍝⍝ Utility functions
|
||||
|
||||
⍝ convert to uppercase
|
||||
UpCase ← { 1 ⎕C ⍵ }
|
||||
|
||||
⍝ remove non-letters
|
||||
JustLetters ← { ⍵ /⍨ ⍵∊⎕A }
|
||||
|
||||
⍝ replace 'J's with 'I's
|
||||
ReplaceJ ← { ('J' ⎕R 'I') ⍵ }
|
||||
|
||||
⍝ Insert an 'X' between repeated letters
|
||||
SplitDouble ← { (' '⎕R'X') ⍵ \⍨ 1,~⍵=1⌽⍵ }
|
||||
|
||||
⍝ Append an 'X' if the message is not of even length
|
||||
PadEven ← { ⍵,(2|≢⍵) ⍴ 'X' }
|
||||
|
||||
⍝ Split text up into letter pairs
|
||||
Pairs ← { (1=2|⍳≢⍵) ⊂ ∊ ⍵ }
|
||||
|
||||
⍝ Group text into chunks of five letters
|
||||
Groups ← { (1=5|⍳≢⍵) ⊂ ∊ ⍵ }
|
||||
|
||||
⍝ Shift within 1-5 based on left arg (0 for +1,1 for -1)
|
||||
Shift ← { ⍺ ← 0 ⋄ 1+5|(⍺+1)⌷⍵,3+⍵ }
|
||||
|
||||
⍝⍝⍝⍝ Playfair implementation
|
||||
|
||||
⍝ All the things we have to do to the plaintext, chained together
|
||||
PreparePlaintext ← { PadEven SplitDouble ReplaceJ JustLetters UpCase ∊ ⍵ }
|
||||
|
||||
⍝ Ditto for ciphertext
|
||||
PrepareCiphertext ← { JustLetters UpCase ∊ ⍵ }
|
||||
|
||||
⍝ Create the grid from the key
|
||||
PrepareKey ← { 5 5⍴ ∪ ReplaceJ (JustLetters UpCase ⍵),⎕A }
|
||||
|
||||
⍝ Encode or decode a single pair of letters
|
||||
∇resultPair ← grid TransformPair args;mode;inPair;l;r;i1;j1;i2;j2
|
||||
mode inPair ← args
|
||||
l r ← inPair
|
||||
i1 j1 ← ⊃⍸grid=l
|
||||
i2 j2 ← ⊃⍸grid=r
|
||||
:If i1=i2
|
||||
j1 ← mode Shift j1
|
||||
j2 ← mode Shift j2
|
||||
:Else
|
||||
:If j1=j2
|
||||
i1 ← mode Shift i1
|
||||
i2 ← mode Shift i2
|
||||
:Else
|
||||
j1 j2 ← j2 j1
|
||||
:EndIf
|
||||
:EndIf
|
||||
resultPair ← grid[(i1 j1)(i2 j2)]
|
||||
∇
|
||||
|
||||
⍝ Encode or decode an entire message
|
||||
∇resultText ← grid TransformText args; mode; inText
|
||||
mode inText ← args
|
||||
resultText ← Groups ∊ { grid TransformPair mode ⍵ } ¨ Pairs inText
|
||||
∇
|
||||
|
||||
⍝ Specific transforms for each direction including key and text preparation
|
||||
∇cipher ← key EncodeText plain
|
||||
cipher ← (PrepareKey key) TransformText 0 (PreparePlaintext plain)
|
||||
∇
|
||||
|
||||
∇plain ← key DecodeText cipher
|
||||
plain ← (PrepareKey key) TransformText 1 (PrepareCiphertext cipher)
|
||||
∇
|
||||
|
||||
⍝ Demo
|
||||
key ← 'Playfair example'
|
||||
plain ← 'Hide the gold in the tree stump.'
|
||||
⎕ ← cipher ← key EncodeText plain
|
||||
⎕ ← key DecodeText cipher
|
||||
110
Task/Playfair-cipher/C++/playfair-cipher.cpp
Normal file
110
Task/Playfair-cipher/C++/playfair-cipher.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#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) % 5 ][ (a + 5) % 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" );
|
||||
}
|
||||
71
Task/Playfair-cipher/D/playfair-cipher.d
Normal file
71
Task/Playfair-cipher/D/playfair-cipher.d
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import std.stdio, std.array, std.algorithm, std.range, std.ascii,
|
||||
std.conv, std.string, std.regex, std.typecons;
|
||||
|
||||
string unique(in string s) pure nothrow @safe {
|
||||
string result;
|
||||
foreach (immutable char c; s)
|
||||
if (!result.representation.canFind(c)) // Assumes ASCII string.
|
||||
result ~= c;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Playfair {
|
||||
string from, to;
|
||||
string[string] enc, dec;
|
||||
|
||||
this(in string key, in string from_ = "J", in string to_ = null)
|
||||
pure /*nothrow @safe*/ {
|
||||
this.from = from_;
|
||||
if (to_.empty)
|
||||
this.to = (from_ == "J") ? "I" : "";
|
||||
|
||||
immutable m = _canonicalize(key ~ uppercase)
|
||||
.unique
|
||||
.chunks(5)
|
||||
.map!text
|
||||
.array;
|
||||
auto I5 = 5.iota;
|
||||
|
||||
foreach (immutable R; m)
|
||||
foreach (immutable i, immutable j; cartesianProduct(I5, I5))
|
||||
if (i != j)
|
||||
enc[[R[i], R[j]]] = [R[(i + 1) % 5], R[(j+1) % 5]];
|
||||
|
||||
foreach (immutable r; I5) {
|
||||
immutable c = m.transversal(r).array;
|
||||
foreach (immutable i, immutable j; cartesianProduct(I5, I5))
|
||||
if (i != j)
|
||||
enc[[c[i], c[j]]] = [c[(i + 1) % 5], c[(j+1) % 5]];
|
||||
}
|
||||
|
||||
foreach (i1, j1, i2, j2; cartesianProduct(I5, I5, I5, I5))
|
||||
if (i1 != i2 && j1 != j2)
|
||||
enc[[m[i1][j1], m[i2][j2]]] = [m[i1][j2], m[i2][j1]];
|
||||
|
||||
dec = enc.byKeyValue.map!(t => tuple(t.value, t.key)).assocArray;
|
||||
}
|
||||
|
||||
private string _canonicalize(in string s) const pure @safe {
|
||||
return s.toUpper.removechars("^A-Z").replace(from, to);
|
||||
}
|
||||
|
||||
string encode(in string s) const /*pure @safe*/ {
|
||||
return _canonicalize(s)
|
||||
.matchAll(r"(.)(?:(?!\1)(.))?")
|
||||
.map!(m => enc[m[0].leftJustify(2, 'X')])
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
string decode(in string s) const pure @safe {
|
||||
return _canonicalize(s).chunks(2).map!(p => dec[p.text]).join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
void main() /*@safe*/ {
|
||||
/*immutable*/ const pf = Playfair("Playfair example");
|
||||
immutable orig = "Hide the gold in...the TREESTUMP!!!";
|
||||
writeln("Original: ", orig);
|
||||
immutable enc = pf.encode(orig);
|
||||
writeln(" Encoded: ", enc);
|
||||
writeln(" Decoded: ", pf.decode(enc));
|
||||
}
|
||||
156
Task/Playfair-cipher/FreeBASIC/playfair-cipher.basic
Normal file
156
Task/Playfair-cipher/FreeBASIC/playfair-cipher.basic
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
' FB 1.05.0 Win64
|
||||
|
||||
Enum PlayFairOption
|
||||
noQ
|
||||
iEqualsJ
|
||||
End Enum
|
||||
|
||||
Dim Shared pfo As PlayFairOption '' set this before calling buildTable
|
||||
Dim Shared table(1 To 5, 1 To 5) As UInteger
|
||||
|
||||
Sub buildTable(keyword As String)
|
||||
Dim used(1 To 26) As Boolean '' all false by default
|
||||
If pfo = noQ Then
|
||||
used(17) = True
|
||||
Else
|
||||
used(10) = True
|
||||
End If
|
||||
Dim As String alphabet = UCase(keyword) + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
Dim As UInteger i = 1, j = 1, k
|
||||
Dim As Integer c
|
||||
For k = 0 To Len(alphabet) - 1
|
||||
c = alphabet[k] - 64
|
||||
If c < 1 OrElse c > 26 Then Continue For
|
||||
If Not used(c) Then
|
||||
table(i, j) = c
|
||||
used(c) = True
|
||||
j += 1
|
||||
If j = 6 Then
|
||||
i += 1
|
||||
If i = 6 Then Return '' table has been filled
|
||||
j = 1
|
||||
End If
|
||||
End If
|
||||
Next k
|
||||
End Sub
|
||||
|
||||
Function getCleanText(plainText As String) As String
|
||||
plainText = UCase(plainText) '' ensure everything is upper case
|
||||
' get rid of any non-letters and insert X between duplicate letters
|
||||
Dim As String cleanText = "", prevChar = "", nextChar
|
||||
For i As UInteger = 1 To Len(plainText)
|
||||
nextChar = Mid(plainText, i, 1)
|
||||
' It appears that Q should be omitted altogether if noQ option is specified - we assume so anyway
|
||||
If nextChar < "A" OrElse nextChar > "Z" OrElse (nextChar = "Q" AndAlso pfo = noQ) Then Continue For
|
||||
' If iEqualsJ option specified, replace J with I
|
||||
If nextChar = "J" AndAlso pfo = iEqualsJ Then nextChar = "I"
|
||||
If nextChar <> prevChar Then
|
||||
cleanText += nextChar
|
||||
Else
|
||||
cleanText += "X" + nextChar
|
||||
End If
|
||||
prevChar = nextChar
|
||||
Next
|
||||
If Len(cleanText) Mod 2 = 1 Then '' dangling letter at end so add another letter to complete digram
|
||||
If Right(cleanText, 1) <> "X" Then
|
||||
cleanText += "X"
|
||||
Else
|
||||
cleanText += "Z"
|
||||
End If
|
||||
End If
|
||||
Return cleanText
|
||||
End Function
|
||||
|
||||
Sub findChar(c As uInteger, ByRef row As UInteger, ByRef col As UInteger)
|
||||
For i As UInteger = 1 To 5
|
||||
For j As UInteger = 1 To 5
|
||||
If table(i, j) = c Then
|
||||
row = i
|
||||
col = j
|
||||
Return
|
||||
End If
|
||||
Next j
|
||||
Next i
|
||||
End Sub
|
||||
|
||||
Function encodePlayfair(plainText As String) As String
|
||||
Dim As String cleanText = getCleanText(plainText)
|
||||
Dim As String digram, cipherDigram, cipherText = ""
|
||||
Dim As UInteger length = Len(cleanText)
|
||||
Dim As UInteger char1, char2, row1, col1, row2, col2
|
||||
For i As UInteger = 1 To length Step 2
|
||||
digram = Mid(cleanText, i, 2)
|
||||
char1 = digram[0] - 64
|
||||
char2 = digram[1] - 64
|
||||
findChar char1, row1, col1
|
||||
findChar char2, row2, col2
|
||||
If row1 = row2 Then
|
||||
cipherDigram = Chr(table(row1, col1 Mod 5 + 1) + 64)
|
||||
cipherDigram += Chr(table(row2, col2 Mod 5 + 1) + 64)
|
||||
ElseIf col1 = col2 Then
|
||||
cipherDigram = Chr(table(row1 Mod 5 + 1, col1) + 64)
|
||||
cipherDigram += Chr(table(row2 Mod 5 + 1, col2) + 64)
|
||||
Else
|
||||
cipherDigram = Chr(table(row1, col2) + 64)
|
||||
cipherDigram += Chr(table(row2, col1) + 64)
|
||||
End If
|
||||
cipherText += cipherDigram
|
||||
If i < length Then cipherText += " "
|
||||
Next i
|
||||
Return cipherText
|
||||
End Function
|
||||
|
||||
Function decodePlayfair(cipherText As String) As String
|
||||
Dim As String digram, cipherDigram, decodedText = ""
|
||||
Dim As UInteger length = Len(cipherText)
|
||||
Dim As UInteger char1, char2, row1, col1, row2, col2
|
||||
For i As UInteger = 1 To length Step 3 '' cipherText will include spaces so we need to skip them
|
||||
cipherDigram = Mid(cipherText, i, 2)
|
||||
char1 = cipherDigram[0] - 64
|
||||
char2 = cipherDigram[1] - 64
|
||||
findChar char1, row1, col1
|
||||
findChar char2, row2, col2
|
||||
If row1 = row2 Then
|
||||
digram = Chr(table(row1, IIf(col1 > 1, col1 - 1, 5)) + 64)
|
||||
digram += Chr(table(row2, IIf(col2 > 1, col2 - 1, 5)) + 64)
|
||||
ElseIf col1 = col2 Then
|
||||
digram = Chr(table(IIf(row1 > 1, row1 - 1, 5), col1) + 64)
|
||||
digram += Chr(table(IIf(row2 > 1, row2 - 1, 5), col2) + 64)
|
||||
Else
|
||||
digram = Chr(table(row1, col2) + 64)
|
||||
digram += Chr(table(row2, col1) + 64)
|
||||
End If
|
||||
decodedText += digram
|
||||
If i < length Then decodedText += " "
|
||||
Next i
|
||||
Return decodedText
|
||||
End Function
|
||||
|
||||
Dim As String keyword, ignoreQ, plainText, encodedText, decodedText
|
||||
Line Input "Enter Playfair keyword : "; keyword
|
||||
|
||||
Do
|
||||
Line Input "Ignore Q when buiding table y/n : "; ignoreQ
|
||||
ignoreQ = LCase(ignoreQ)
|
||||
Loop Until ignoreQ = "y" Or ignoreQ = "n"
|
||||
|
||||
pfo = IIf(ignoreQ = "y", noQ, iEqualsJ)
|
||||
buildTable(keyword)
|
||||
Print "The table to be used is : " : Print
|
||||
For i As UInteger = 1 To 5
|
||||
For j As UInteger = 1 To 5
|
||||
Print Chr(table(i, j) + 64); " ";
|
||||
Next j
|
||||
Print
|
||||
Next i
|
||||
|
||||
Print
|
||||
Line Input "Enter plain text : "; plainText
|
||||
Print
|
||||
encodedText = encodePlayfair(plainText)
|
||||
Print "Encoded text is : "; encodedText
|
||||
decodedText = decodePlayFair(encodedText)
|
||||
Print "Decoded text is : "; decodedText
|
||||
Print
|
||||
Print "Press any key to quit"
|
||||
Sleep
|
||||
208
Task/Playfair-cipher/Go/playfair-cipher.go
Normal file
208
Task/Playfair-cipher/Go/playfair-cipher.go
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type playfairOption int
|
||||
|
||||
const (
|
||||
noQ playfairOption = iota
|
||||
iEqualsJ
|
||||
)
|
||||
|
||||
type playfair struct {
|
||||
keyword string
|
||||
pfo playfairOption
|
||||
table [5][5]byte
|
||||
}
|
||||
|
||||
func (p *playfair) init() {
|
||||
// Build table.
|
||||
var used [26]bool // all elements false
|
||||
if p.pfo == noQ {
|
||||
used[16] = true // Q used
|
||||
} else {
|
||||
used[9] = true // J used
|
||||
}
|
||||
alphabet := strings.ToUpper(p.keyword) + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
for i, j, k := 0, 0, 0; k < len(alphabet); k++ {
|
||||
c := alphabet[k]
|
||||
if c < 'A' || c > 'Z' {
|
||||
continue
|
||||
}
|
||||
d := int(c - 65)
|
||||
if !used[d] {
|
||||
p.table[i][j] = c
|
||||
used[d] = true
|
||||
j++
|
||||
if j == 5 {
|
||||
i++
|
||||
if i == 5 {
|
||||
break // table has been filled
|
||||
}
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *playfair) getCleanText(plainText string) string {
|
||||
// Ensure everything is upper case.
|
||||
plainText = strings.ToUpper(plainText)
|
||||
// Get rid of any non-letters and insert X between duplicate letters.
|
||||
var cleanText strings.Builder
|
||||
// Safe to assume null byte won't be present in plainText.
|
||||
prevByte := byte('\000')
|
||||
for i := 0; i < len(plainText); i++ {
|
||||
nextByte := plainText[i]
|
||||
// It appears that Q should be omitted altogether if NO_Q option is specified;
|
||||
// we assume so anyway.
|
||||
if nextByte < 'A' || nextByte > 'Z' || (nextByte == 'Q' && p.pfo == noQ) {
|
||||
continue
|
||||
}
|
||||
// If iEqualsJ option specified, replace J with I.
|
||||
if nextByte == 'J' && p.pfo == iEqualsJ {
|
||||
nextByte = 'I'
|
||||
}
|
||||
if nextByte != prevByte {
|
||||
cleanText.WriteByte(nextByte)
|
||||
} else {
|
||||
cleanText.WriteByte('X')
|
||||
cleanText.WriteByte(nextByte)
|
||||
}
|
||||
prevByte = nextByte
|
||||
}
|
||||
l := cleanText.Len()
|
||||
if l%2 == 1 {
|
||||
// Dangling letter at end so add another letter to complete digram.
|
||||
if cleanText.String()[l-1] != 'X' {
|
||||
cleanText.WriteByte('X')
|
||||
} else {
|
||||
cleanText.WriteByte('Z')
|
||||
}
|
||||
}
|
||||
return cleanText.String()
|
||||
}
|
||||
|
||||
func (p *playfair) findByte(c byte) (int, int) {
|
||||
for i := 0; i < 5; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
if p.table[i][j] == c {
|
||||
return i, j
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
func (p *playfair) encode(plainText string) string {
|
||||
cleanText := p.getCleanText(plainText)
|
||||
var cipherText strings.Builder
|
||||
l := len(cleanText)
|
||||
for i := 0; i < l; i += 2 {
|
||||
row1, col1 := p.findByte(cleanText[i])
|
||||
row2, col2 := p.findByte(cleanText[i+1])
|
||||
switch {
|
||||
case row1 == row2:
|
||||
cipherText.WriteByte(p.table[row1][(col1+1)%5])
|
||||
cipherText.WriteByte(p.table[row2][(col2+1)%5])
|
||||
case col1 == col2:
|
||||
cipherText.WriteByte(p.table[(row1+1)%5][col1])
|
||||
cipherText.WriteByte(p.table[(row2+1)%5][col2])
|
||||
default:
|
||||
cipherText.WriteByte(p.table[row1][col2])
|
||||
cipherText.WriteByte(p.table[row2][col1])
|
||||
}
|
||||
if i < l-1 {
|
||||
cipherText.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
return cipherText.String()
|
||||
}
|
||||
|
||||
func (p *playfair) decode(cipherText string) string {
|
||||
var decodedText strings.Builder
|
||||
l := len(cipherText)
|
||||
// cipherText will include spaces so we need to skip them.
|
||||
for i := 0; i < l; i += 3 {
|
||||
row1, col1 := p.findByte(cipherText[i])
|
||||
row2, col2 := p.findByte(cipherText[i+1])
|
||||
switch {
|
||||
case row1 == row2:
|
||||
temp := 4
|
||||
if col1 > 0 {
|
||||
temp = col1 - 1
|
||||
}
|
||||
decodedText.WriteByte(p.table[row1][temp])
|
||||
temp = 4
|
||||
if col2 > 0 {
|
||||
temp = col2 - 1
|
||||
}
|
||||
decodedText.WriteByte(p.table[row2][temp])
|
||||
case col1 == col2:
|
||||
temp := 4
|
||||
if row1 > 0 {
|
||||
temp = row1 - 1
|
||||
}
|
||||
decodedText.WriteByte(p.table[temp][col1])
|
||||
temp = 4
|
||||
if row2 > 0 {
|
||||
temp = row2 - 1
|
||||
}
|
||||
decodedText.WriteByte(p.table[temp][col2])
|
||||
default:
|
||||
decodedText.WriteByte(p.table[row1][col2])
|
||||
decodedText.WriteByte(p.table[row2][col1])
|
||||
}
|
||||
if i < l-1 {
|
||||
decodedText.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
return decodedText.String()
|
||||
}
|
||||
|
||||
func (p *playfair) printTable() {
|
||||
fmt.Println("The table to be used is :\n")
|
||||
for i := 0; i < 5; i++ {
|
||||
for j := 0; j < 5; j++ {
|
||||
fmt.Printf("%c ", p.table[i][j])
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
fmt.Print("Enter Playfair keyword : ")
|
||||
scanner.Scan()
|
||||
keyword := scanner.Text()
|
||||
var ignoreQ string
|
||||
for ignoreQ != "y" && ignoreQ != "n" {
|
||||
fmt.Print("Ignore Q when building table y/n : ")
|
||||
scanner.Scan()
|
||||
ignoreQ = strings.ToLower(scanner.Text())
|
||||
}
|
||||
pfo := noQ
|
||||
if ignoreQ == "n" {
|
||||
pfo = iEqualsJ
|
||||
}
|
||||
var table [5][5]byte
|
||||
pf := &playfair{keyword, pfo, table}
|
||||
pf.init()
|
||||
pf.printTable()
|
||||
fmt.Print("\nEnter plain text : ")
|
||||
scanner.Scan()
|
||||
plainText := scanner.Text()
|
||||
if err := scanner.Err(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "reading standard input:", err)
|
||||
return
|
||||
}
|
||||
encodedText := pf.encode(plainText)
|
||||
fmt.Println("\nEncoded text is :", encodedText)
|
||||
decodedText := pf.decode(encodedText)
|
||||
fmt.Println("Deccoded text is :", decodedText)
|
||||
}
|
||||
101
Task/Playfair-cipher/Haskell/playfair-cipher.hs
Normal file
101
Task/Playfair-cipher/Haskell/playfair-cipher.hs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import Control.Monad (guard)
|
||||
import Data.Array (Array, assocs, elems, listArray, (!))
|
||||
import Data.Char (toUpper)
|
||||
import Data.List (nub, (\\))
|
||||
import Data.List.Split (chunksOf)
|
||||
import Data.Maybe (listToMaybe)
|
||||
import Data.String.Utils (replace)
|
||||
|
||||
type Square a = Array (Int, Int) a
|
||||
|
||||
-- | Turns a list into an n*m-array.
|
||||
array2D ::
|
||||
(Int, Int) -- ^ n * m
|
||||
-> [e] -> Square e
|
||||
array2D maxCoord = listArray ((1, 1), maxCoord)
|
||||
|
||||
-- | Generates a playfair table starting with the specified string.
|
||||
--
|
||||
-- >>> makeTable "hello"
|
||||
-- "HELOABCDFGIKMNPQRSTUVWXYZ"
|
||||
makeTable :: String -> String
|
||||
makeTable k = nub key ++ (alpha \\ key)
|
||||
where
|
||||
alpha = ['A' .. 'Z'] \\ "J"
|
||||
key = map toUpper =<< words k
|
||||
|
||||
-- | Turns a playfair table into a 5*5 alphabet square.
|
||||
makeSquare :: [a] -> Square a
|
||||
makeSquare = array2D (5, 5)
|
||||
|
||||
-- | Displays a playfair square, formatted as a square.
|
||||
showSquare :: Square Char -> String
|
||||
showSquare d = unlines $ chunksOf 5 (elems d)
|
||||
|
||||
-- | Given a value and an association list of x-coordinate * y-coordinate * value, returns the coordinates
|
||||
getIndex' :: (Eq a) => a -> [((Int, Int), a)] -> Maybe (Int, Int)
|
||||
getIndex' el = fmap fst . listToMaybe . filter ((== el) . snd)
|
||||
|
||||
encodePair, decodePair :: Eq a => Square a -> (a, a) -> Maybe (a, a)
|
||||
encodePair = pairHelper (\x -> if x == 5 then 1 else x + 1)
|
||||
decodePair = pairHelper (\x -> if x == 1 then 5 else x - 1)
|
||||
|
||||
pairHelper :: (Eq t)
|
||||
=> (Int -> Int) -- ^ a function used for wrapping around the square
|
||||
-> Square t -- ^ a playfair square
|
||||
-> (t, t) -- ^ two characters
|
||||
-> Maybe (t, t) -- ^ the two resulting/encoded characters
|
||||
pairHelper adjust sqr (c1, c2) =
|
||||
do let ps = assocs sqr
|
||||
-- assigns an association list of (x-coord * y-coord) * value to ps
|
||||
(x1, y1) <- getIndex' c1 ps
|
||||
(x2, y2) <- getIndex' c2 ps
|
||||
-- returns the coordinates of two values in the square
|
||||
-- these will later be swapped
|
||||
guard $ c1 /= c2
|
||||
-- the characters (and coordinates) cannot be the same
|
||||
let get x = sqr ! x
|
||||
-- a small utility function for extracting a value from the square
|
||||
Just $
|
||||
-- wrap the coordinates around and find the encrypted characters
|
||||
case () of
|
||||
() | y1 == y2 ->
|
||||
(get (adjust x1, y1), get (adjust x2, y2))
|
||||
| x1 == x2 ->
|
||||
(get (x1, adjust y1), get (x2, adjust y2))
|
||||
| otherwise ->
|
||||
(get (x1, y2), get (x2, y1))
|
||||
|
||||
-- | Turns two characters into a tuple.
|
||||
parsePair :: String -> [(Char, Char)]
|
||||
parsePair = fmap (\[x, y] -> (x, y)) . words . fmap toUpper
|
||||
|
||||
-- | Turns a tuple of two characters into a string.
|
||||
unparsePair :: [(Char, Char)] -> String
|
||||
unparsePair = unwords . fmap (\(x, y) -> [x, y])
|
||||
|
||||
codeHelper :: (Square Char -> (Char, Char) -> Maybe (Char, Char))
|
||||
-> String -> String -> Maybe String
|
||||
codeHelper subs key =
|
||||
fmap unparsePair .
|
||||
mapM (subs (makeSquare $ makeTable key)) .
|
||||
parsePair
|
||||
|
||||
playfair, unplayfair :: String -> String -> Maybe String
|
||||
playfair key = codeHelper encodePair key . formatEncode
|
||||
unplayfair = codeHelper decodePair
|
||||
|
||||
formatEncode :: String -> String
|
||||
formatEncode =
|
||||
map toUpper .
|
||||
unwords .
|
||||
map (\[x, y] -> if x == y then [x, 'x'] else [x, y]) .
|
||||
chunksOf 2 .
|
||||
replace "j" "i" .
|
||||
concatMap adjustLength .
|
||||
words .
|
||||
filter (\n -> n `elem` (['A'..'Z'] ++ ['a'..'z']))
|
||||
where
|
||||
adjustLength str
|
||||
| odd (length str) = str ++ "x"
|
||||
| otherwise = str
|
||||
36
Task/Playfair-cipher/J/playfair-cipher-1.j
Normal file
36
Task/Playfair-cipher/J/playfair-cipher-1.j
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
choose=: verb define
|
||||
sel=. 'Q' e. y
|
||||
alph=: (sel { 'JQ') -.~ a. {~ 65 + i.26
|
||||
norm=: [: dedouble alph restrict ('I' I.@:=&'J'@]} ])`(-.&'Q')@.sel@toupper
|
||||
''
|
||||
)
|
||||
|
||||
restrict=: ] -. -.~
|
||||
|
||||
splitDigraph=: ,`([,'X',])@.((= {.) *. 2 | #@])
|
||||
dedouble=: splitDigraph/&.|. NB. progressively split digraphs in string
|
||||
|
||||
choose 'Q'
|
||||
|
||||
setkey=: verb define
|
||||
key=. ~.norm y,alph
|
||||
ref=: ,/ 2{."1 ~."1 (,"0/~ alph) ,"1 norm 'XQV'
|
||||
mode=. #. =/"2 inds=. 5 5#:key i. ref
|
||||
inds0=. (0 3,:2 1)&{@,"2 inds
|
||||
inds1=. 5|1 0 +"1 inds NB. same column
|
||||
inds2=. 5|0 1 +"1 inds NB. same row
|
||||
alt=: key {~ 5 #. mode {"_1 inds0 ,"2 3 inds1 ,:"2 inds2
|
||||
i. 0 0
|
||||
)
|
||||
|
||||
pairs=: verb define
|
||||
2{."1 -.&' '"1 ~."1 (_2]\ norm y) ,"1 'XQV'
|
||||
)
|
||||
|
||||
encrypt=: verb define
|
||||
;:inv ;/ alt{~ref i. pairs y
|
||||
)
|
||||
|
||||
decrypt=: verb define
|
||||
, ref{~alt i. pairs y
|
||||
)
|
||||
7
Task/Playfair-cipher/J/playfair-cipher-2.j
Normal file
7
Task/Playfair-cipher/J/playfair-cipher-2.j
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
choose 'IJ'
|
||||
|
||||
setkey 'playfair example'
|
||||
encrypt 'Hide the gold in the tree stump'
|
||||
BM OD ZB XD NA BE KU DM UI XM MO UV IF
|
||||
decrypt 'BM OD ZB XD NA BE KU DM UI XM MO UV IF'
|
||||
HIDETHEGOLDINTHETREXESTUMP
|
||||
104
Task/Playfair-cipher/Java/playfair-cipher-1.java
Normal file
104
Task/Playfair-cipher/Java/playfair-cipher-1.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import java.awt.Point;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class PlayfairCipher {
|
||||
private static char[][] charTable;
|
||||
private static Point[] positions;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
|
||||
String key = prompt("Enter an encryption key (min length 6): ", sc, 6);
|
||||
String txt = prompt("Enter the message: ", sc, 1);
|
||||
String jti = prompt("Replace J with I? y/n: ", sc, 1);
|
||||
|
||||
boolean changeJtoI = jti.equalsIgnoreCase("y");
|
||||
|
||||
createTable(key, changeJtoI);
|
||||
|
||||
String enc = encode(prepareText(txt, changeJtoI));
|
||||
|
||||
System.out.printf("%nEncoded message: %n%s%n", enc);
|
||||
System.out.printf("%nDecoded message: %n%s%n", decode(enc));
|
||||
}
|
||||
|
||||
private static String prompt(String promptText, Scanner sc, int minLen) {
|
||||
String s;
|
||||
do {
|
||||
System.out.print(promptText);
|
||||
s = sc.nextLine().trim();
|
||||
} while (s.length() < minLen);
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String prepareText(String s, boolean changeJtoI) {
|
||||
s = s.toUpperCase().replaceAll("[^A-Z]", "");
|
||||
return changeJtoI ? s.replace("J", "I") : s.replace("Q", "");
|
||||
}
|
||||
|
||||
private static void createTable(String key, boolean changeJtoI) {
|
||||
charTable = new char[5][5];
|
||||
positions = new Point[26];
|
||||
|
||||
String s = prepareText(key + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", changeJtoI);
|
||||
|
||||
int len = s.length();
|
||||
for (int i = 0, k = 0; i < len; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (positions[c - 'A'] == null) {
|
||||
charTable[k / 5][k % 5] = c;
|
||||
positions[c - 'A'] = new Point(k % 5, k / 5);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String encode(String s) {
|
||||
StringBuilder sb = new StringBuilder(s);
|
||||
|
||||
for (int i = 0; i < sb.length(); i += 2) {
|
||||
|
||||
if (i == sb.length() - 1)
|
||||
sb.append(sb.length() % 2 == 1 ? 'X' : "");
|
||||
|
||||
else if (sb.charAt(i) == sb.charAt(i + 1))
|
||||
sb.insert(i + 1, 'X');
|
||||
}
|
||||
return codec(sb, 1);
|
||||
}
|
||||
|
||||
private static String decode(String s) {
|
||||
return codec(new StringBuilder(s), 4);
|
||||
}
|
||||
|
||||
private static String codec(StringBuilder text, int direction) {
|
||||
int len = text.length();
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
char a = text.charAt(i);
|
||||
char b = text.charAt(i + 1);
|
||||
|
||||
int row1 = positions[a - 'A'].y;
|
||||
int row2 = positions[b - 'A'].y;
|
||||
int col1 = positions[a - 'A'].x;
|
||||
int col2 = positions[b - 'A'].x;
|
||||
|
||||
if (row1 == row2) {
|
||||
col1 = (col1 + direction) % 5;
|
||||
col2 = (col2 + direction) % 5;
|
||||
|
||||
} else if (col1 == col2) {
|
||||
row1 = (row1 + direction) % 5;
|
||||
row2 = (row2 + direction) % 5;
|
||||
|
||||
} else {
|
||||
int tmp = col1;
|
||||
col1 = col2;
|
||||
col2 = tmp;
|
||||
}
|
||||
|
||||
text.setCharAt(i, charTable[row1][col1]);
|
||||
text.setCharAt(i + 1, charTable[row2][col2]);
|
||||
}
|
||||
return text.toString();
|
||||
}
|
||||
}
|
||||
205
Task/Playfair-cipher/Java/playfair-cipher-2.java
Normal file
205
Task/Playfair-cipher/Java/playfair-cipher-2.java
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
import java.util.Scanner;
|
||||
|
||||
public class PlayfairCipherEncryption
|
||||
{
|
||||
private String KeyWord = new String();
|
||||
private String Key = new String();
|
||||
private char matrix_arr[][] = new char[5][5];
|
||||
|
||||
public void setKey(String k)
|
||||
{
|
||||
String K_adjust = new String();
|
||||
boolean flag = false;
|
||||
K_adjust = K_adjust + k.charAt(0);
|
||||
for (int i = 1; i < k.length(); i++)
|
||||
{
|
||||
for (int j = 0; j < K_adjust.length(); j++)
|
||||
{
|
||||
if (k.charAt(i) == K_adjust.charAt(j))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
if (flag == false)
|
||||
K_adjust = K_adjust + k.charAt(i);
|
||||
flag = false;
|
||||
}
|
||||
KeyWord = K_adjust;
|
||||
}
|
||||
|
||||
public void KeyGen()
|
||||
{
|
||||
boolean flag = true;
|
||||
char current;
|
||||
Key = KeyWord;
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
current = (char) (i + 97);
|
||||
if (current == 'j')
|
||||
continue;
|
||||
for (int j = 0; j < KeyWord.length(); j++)
|
||||
{
|
||||
if (current == KeyWord.charAt(j))
|
||||
{
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
Key = Key + current;
|
||||
flag = true;
|
||||
}
|
||||
System.out.println(Key);
|
||||
matrix();
|
||||
}
|
||||
|
||||
private void matrix()
|
||||
{
|
||||
int counter = 0;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
matrix_arr[i][j] = Key.charAt(counter);
|
||||
System.out.print(matrix_arr[i][j] + " ");
|
||||
counter++;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private String format(String old_text)
|
||||
{
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
String text = new String();
|
||||
len = old_text.length();
|
||||
for (int tmp = 0; tmp < len; tmp++)
|
||||
{
|
||||
if (old_text.charAt(tmp) == 'j')
|
||||
{
|
||||
text = text + 'i';
|
||||
}
|
||||
else
|
||||
text = text + old_text.charAt(tmp);
|
||||
}
|
||||
len = text.length();
|
||||
for (i = 0; i < len; i = i + 2)
|
||||
{
|
||||
if (text.charAt(i + 1) == text.charAt(i))
|
||||
{
|
||||
text = text.substring(0, i + 1) + 'x' + text.substring(i + 1);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private String[] Divid2Pairs(String new_string)
|
||||
{
|
||||
String Original = format(new_string);
|
||||
int size = Original.length();
|
||||
if (size % 2 != 0)
|
||||
{
|
||||
size++;
|
||||
Original = Original + 'x';
|
||||
}
|
||||
String x[] = new String[size / 2];
|
||||
int counter = 0;
|
||||
for (int i = 0; i < size / 2; i++)
|
||||
{
|
||||
x[i] = Original.substring(counter, counter + 2);
|
||||
counter = counter + 2;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
public int[] GetDiminsions(char letter)
|
||||
{
|
||||
int[] key = new int[2];
|
||||
if (letter == 'j')
|
||||
letter = 'i';
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
if (matrix_arr[i][j] == letter)
|
||||
{
|
||||
key[0] = i;
|
||||
key[1] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public String encryptMessage(String Source)
|
||||
{
|
||||
String src_arr[] = Divid2Pairs(Source);
|
||||
String Code = new String();
|
||||
char one;
|
||||
char two;
|
||||
int part1[] = new int[2];
|
||||
int part2[] = new int[2];
|
||||
for (int i = 0; i < src_arr.length; i++)
|
||||
{
|
||||
one = src_arr[i].charAt(0);
|
||||
two = src_arr[i].charAt(1);
|
||||
part1 = GetDiminsions(one);
|
||||
part2 = GetDiminsions(two);
|
||||
if (part1[0] == part2[0])
|
||||
{
|
||||
if (part1[1] < 4)
|
||||
part1[1]++;
|
||||
else
|
||||
part1[1] = 0;
|
||||
if (part2[1] < 4)
|
||||
part2[1]++;
|
||||
else
|
||||
part2[1] = 0;
|
||||
}
|
||||
else if (part1[1] == part2[1])
|
||||
{
|
||||
if (part1[0] < 4)
|
||||
part1[0]++;
|
||||
else
|
||||
part1[0] = 0;
|
||||
if (part2[0] < 4)
|
||||
part2[0]++;
|
||||
else
|
||||
part2[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int temp = part1[1];
|
||||
part1[1] = part2[1];
|
||||
part2[1] = temp;
|
||||
}
|
||||
Code = Code + matrix_arr[part1[0]][part1[1]]
|
||||
+ matrix_arr[part2[0]][part2[1]];
|
||||
}
|
||||
return Code;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
PlayfairCipherEncryption x = new PlayfairCipherEncryption();
|
||||
Scanner sc = new Scanner(System.in);
|
||||
System.out.println("Enter a keyword:");
|
||||
String keyword = sc.next();
|
||||
x.setKey(keyword);
|
||||
x.KeyGen();
|
||||
System.out
|
||||
.println("Enter word to encrypt: (Make sure length of message is even)");
|
||||
String key_input = sc.next();
|
||||
if (key_input.length() % 2 == 0)
|
||||
{
|
||||
System.out.println("Encryption: " + x.encryptMessage(key_input));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Message length should be even");
|
||||
}
|
||||
sc.close();
|
||||
}
|
||||
}
|
||||
60
Task/Playfair-cipher/Julia/playfair-cipher.julia
Normal file
60
Task/Playfair-cipher/Julia/playfair-cipher.julia
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
function playfair(key, txt, isencode=true, from = "J", to = "")
|
||||
to = (to == "" && from == "J") ? "I" : to
|
||||
|
||||
function canonical(s, dup_toX=true)
|
||||
s = replace(replace(uppercase(s), from => to), r"[^A-Z]" => "")
|
||||
a, dupcount = [c for c in s], 0
|
||||
for i in 1:2:length(a)-1
|
||||
if s[i] == s[i + 1]
|
||||
dup_toX && splice!(a, i+1+dupcount:i+dupcount, 'X')
|
||||
dupcount += 1
|
||||
end
|
||||
end
|
||||
s = String(a)
|
||||
return isodd(length(s)) ? s * "X" : s
|
||||
end
|
||||
|
||||
# Translate key into an encoding 5x5 translation matrix.
|
||||
keyletters = unique([c for c in canonical(key * "ABCDEFGHIJKLMNOPQRSTUVWXYZ", false)])
|
||||
m = Char.((reshape(UInt8.(keyletters[1:25]), 5, 5)'))
|
||||
|
||||
# encod is a dictionary of letter pairs for encoding.
|
||||
encod = Dict()
|
||||
|
||||
# Map pairs in same row or same column of matrix m.
|
||||
for i in 1:5, j in 1:5, k in 1:5
|
||||
if j != k
|
||||
encod[m[i, j] * m[i, k]] = m[i, mod1(j + 1, 5)] * m[i, mod1(k + 1, 5)]
|
||||
end
|
||||
if i != k
|
||||
encod[m[i, j] * m[k, j]] = m[mod1(i + 1, 5), j] * m[mod1(k + 1, 5), j]
|
||||
end
|
||||
# Map pairs not on same row or same column.
|
||||
for l in 1:5
|
||||
if i != k && j != l
|
||||
encod[m[i, j] * m[k, l]] = m[i, l] * m[k, j]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Get array of pairs of letters from text.
|
||||
canontxt = canonical(txt)
|
||||
letterpairs = [canontxt[i:i+1] for i in 1:2:length(canontxt)-1]
|
||||
|
||||
if isencode
|
||||
# Encode text
|
||||
return join([encod[pair] for pair in letterpairs], " ")
|
||||
else
|
||||
# Decode text
|
||||
decod = Dict((v, k) for (k, v) in encod)
|
||||
return join([decod[pair] for pair in letterpairs], " ")
|
||||
end
|
||||
end
|
||||
|
||||
orig = "Hide the gold in...the TREESTUMP!!!"
|
||||
println("Original: ", orig)
|
||||
|
||||
encoded = playfair("Playfair example", orig)
|
||||
println("Encoded: ", encoded)
|
||||
|
||||
println("Decoded: ", playfair("Playfair example", encoded, false))
|
||||
133
Task/Playfair-cipher/Kotlin/playfair-cipher.kotlin
Normal file
133
Task/Playfair-cipher/Kotlin/playfair-cipher.kotlin
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// version 1.0.5-2
|
||||
|
||||
enum class PlayfairOption {
|
||||
NO_Q,
|
||||
I_EQUALS_J
|
||||
}
|
||||
|
||||
class Playfair(keyword: String, val pfo: PlayfairOption) {
|
||||
private val table: Array<CharArray> = Array(5, { CharArray(5) }) // 5 x 5 char array
|
||||
|
||||
init {
|
||||
// build table
|
||||
val used = BooleanArray(26) // all elements false
|
||||
if (pfo == PlayfairOption.NO_Q)
|
||||
used[16] = true // Q used
|
||||
else
|
||||
used[9] = true // J used
|
||||
val alphabet = keyword.toUpperCase() + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
var i = 0
|
||||
var j = 0
|
||||
var c: Char
|
||||
var d: Int
|
||||
for (k in 0 until alphabet.length) {
|
||||
c = alphabet[k]
|
||||
if (c !in 'A'..'Z') continue
|
||||
d = c.toInt() - 65
|
||||
if (!used[d]) {
|
||||
table[i][j] = c
|
||||
used[d] = true
|
||||
if (++j == 5) {
|
||||
if (++i == 5) break // table has been filled
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCleanText(plainText: String): String {
|
||||
val plainText2 = plainText.toUpperCase() // ensure everything is upper case
|
||||
// get rid of any non-letters and insert X between duplicate letters
|
||||
var cleanText = ""
|
||||
var prevChar = '\u0000' // safe to assume null character won't be present in plainText
|
||||
var nextChar: Char
|
||||
for (i in 0 until plainText2.length) {
|
||||
nextChar = plainText2[i]
|
||||
// It appears that Q should be omitted altogether if NO_Q option is specified - we assume so anyway
|
||||
if (nextChar !in 'A'..'Z' || (nextChar == 'Q' && pfo == PlayfairOption.NO_Q)) continue
|
||||
// If I_EQUALS_J option specified, replace J with I
|
||||
if (nextChar == 'J' && pfo == PlayfairOption.I_EQUALS_J) nextChar = 'I'
|
||||
if (nextChar != prevChar)
|
||||
cleanText += nextChar
|
||||
else
|
||||
cleanText += "X" + nextChar
|
||||
prevChar = nextChar
|
||||
}
|
||||
val len = cleanText.length
|
||||
if (len % 2 == 1) { // dangling letter at end so add another letter to complete digram
|
||||
if (cleanText[len - 1] != 'X')
|
||||
cleanText += 'X'
|
||||
else
|
||||
cleanText += 'Z'
|
||||
}
|
||||
return cleanText
|
||||
}
|
||||
|
||||
private fun findChar(c: Char): Pair<Int, Int> {
|
||||
for (i in 0..4)
|
||||
for (j in 0..4)
|
||||
if (table[i][j] == c) return Pair(i, j)
|
||||
return Pair(-1, -1)
|
||||
}
|
||||
|
||||
fun encode(plainText: String): String {
|
||||
val cleanText = getCleanText(plainText)
|
||||
var cipherText = ""
|
||||
val length = cleanText.length
|
||||
for (i in 0 until length step 2) {
|
||||
val (row1, col1) = findChar(cleanText[i])
|
||||
val (row2, col2) = findChar(cleanText[i + 1])
|
||||
cipherText += when {
|
||||
row1 == row2 -> table[row1][(col1 + 1) % 5].toString() + table[row2][(col2 + 1) % 5]
|
||||
col1 == col2 -> table[(row1 + 1) % 5][col1].toString() + table[(row2 + 1) % 5][col2]
|
||||
else -> table[row1][col2].toString() + table[row2][col1]
|
||||
}
|
||||
if (i < length - 1) cipherText += " "
|
||||
}
|
||||
return cipherText
|
||||
}
|
||||
|
||||
fun decode(cipherText: String): String {
|
||||
var decodedText = ""
|
||||
val length = cipherText.length
|
||||
for (i in 0 until length step 3) { // cipherText will include spaces so we need to skip them
|
||||
val (row1, col1) = findChar(cipherText[i])
|
||||
val (row2, col2) = findChar(cipherText[i + 1])
|
||||
decodedText += when {
|
||||
row1 == row2 -> table[row1][if (col1 > 0) col1 - 1 else 4].toString() + table[row2][if (col2 > 0) col2 - 1 else 4]
|
||||
col1 == col2 -> table[if (row1 > 0) row1- 1 else 4][col1].toString() + table[if (row2 > 0) row2 - 1 else 4][col2]
|
||||
else -> table[row1][col2].toString() + table[row2][col1]
|
||||
}
|
||||
if (i < length - 1) decodedText += " "
|
||||
}
|
||||
return decodedText
|
||||
}
|
||||
|
||||
fun printTable() {
|
||||
println("The table to be used is :\n")
|
||||
for (i in 0..4) {
|
||||
for (j in 0..4) print(table[i][j] + " ")
|
||||
println()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
print("Enter Playfair keyword : ")
|
||||
val keyword: String = readLine()!!
|
||||
var ignoreQ: String
|
||||
do {
|
||||
print("Ignore Q when buiding table y/n : ")
|
||||
ignoreQ = readLine()!!.toLowerCase()
|
||||
}
|
||||
while (ignoreQ != "y" && ignoreQ != "n")
|
||||
val pfo = if (ignoreQ == "y") PlayfairOption.NO_Q else PlayfairOption.I_EQUALS_J
|
||||
val playfair = Playfair(keyword, pfo)
|
||||
playfair.printTable()
|
||||
print("\nEnter plain text : ")
|
||||
val plainText: String = readLine()!!
|
||||
val encodedText = playfair.encode(plainText)
|
||||
println("\nEncoded text is : $encodedText")
|
||||
val decodedText = playfair.decode(encodedText)
|
||||
println("Decoded text is : $decodedText")
|
||||
}
|
||||
72
Task/Playfair-cipher/Mathematica/playfair-cipher.math
Normal file
72
Task/Playfair-cipher/Mathematica/playfair-cipher.math
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
ClearAll[MakeTranslationTable, PlayfairCipher, PlayfairDecipher]
|
||||
MakeTranslationTable[tt_List] := Module[{poss, in, out},
|
||||
poss = Tuples[Tuples[Range[5], 2], 2];
|
||||
Table[
|
||||
If[p[[1, 1]] == p[[2, 1]],
|
||||
(* same row *)
|
||||
{in, out} = {p, {{p[[1, 1]], Mod[p[[1, 2]] + 1, 5, 1]}, {p[[2, 1]], Mod[p[[2, 2]] + 1, 5, 1]}}};
|
||||
,
|
||||
If[p[[1, 2]] == p[[2, 2]],
|
||||
(* same column *)
|
||||
{in, out} = {p, {{Mod[p[[1, 1]] + 1, 5, 1], p[[1, 2]]}, {Mod[p[[2, 1]] + 1, 5, 1], p[[2, 2]]}}};
|
||||
,
|
||||
(*rectangle*)
|
||||
{in, out} = {p, {{p[[1, 1]], p[[2, 2]]}, {p[[2, 1]], p[[1, 2]]}}};
|
||||
]
|
||||
];
|
||||
StringJoin[Extract[tt, in]] -> StringJoin[Extract[tt, out]]
|
||||
,
|
||||
{p, poss}
|
||||
]
|
||||
]
|
||||
PlayfairCipher[txt_String, key_String, iisj_ : True] :=
|
||||
Module[{text, tt},
|
||||
text = RemoveDiacritics[ToUpperCase[txt]];
|
||||
tt = RemoveDiacritics[ToUpperCase[key]] <> CharacterRange["A", "Z"];
|
||||
text //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""];
|
||||
tt //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""];
|
||||
If[iisj,
|
||||
tt //= StringReplace["J" -> "I"];
|
||||
text //= StringReplace["J" -> "I"];
|
||||
,
|
||||
tt //= StringReplace["Q" -> ""];
|
||||
text //= StringReplace["Q" -> ""];
|
||||
];
|
||||
tt //= Characters /* DeleteDuplicates;
|
||||
text = FixedPoint[StringReplace[#, x_ ~~ x_ :> x ~~ "X" ~~ x, 1] &, text];
|
||||
If[OddQ[StringLength[text]], text = text <> "X"];
|
||||
If[Length[tt] == 25,
|
||||
tt = Partition[tt, 5];
|
||||
tt = MakeTranslationTable[tt];
|
||||
text = StringPartition[text, 2];
|
||||
StringRiffle[text /. tt, " "]
|
||||
,
|
||||
Print["Something went wrong!"]
|
||||
]
|
||||
]
|
||||
PlayfairDecipher[txt_String, key_String, iisj_ : True] :=
|
||||
Module[{text, tt},
|
||||
text = RemoveDiacritics[ToUpperCase[txt]];
|
||||
tt = RemoveDiacritics[ToUpperCase[key]] <> CharacterRange["A", "Z"];
|
||||
text //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""];
|
||||
tt //= StringReplace[Except[Alternatives @@ CharacterRange["A", "Z"]] -> ""];
|
||||
If[iisj,
|
||||
tt //= StringReplace["J" -> "I"];
|
||||
text //= StringReplace["J" -> "I"];
|
||||
,
|
||||
tt //= StringReplace["Q" -> ""];
|
||||
text //= StringReplace["Q" -> ""];
|
||||
];
|
||||
tt //= Characters /* DeleteDuplicates;
|
||||
If[OddQ[StringLength[text]], text = text <> "X"];
|
||||
If[Length[tt] == 25,
|
||||
tt = Partition[tt, 5];
|
||||
tt = MakeTranslationTable[tt];
|
||||
text = StringPartition[text, 2];
|
||||
StringRiffle[text /. (Reverse /@ tt), " "]
|
||||
,
|
||||
Print["Something went wrong!"]
|
||||
]
|
||||
]
|
||||
PlayfairCipher["Hide the gold in...the TREESTUMP!!!", "Playfair example"]
|
||||
PlayfairDecipher[%, "Playfair example"]
|
||||
165
Task/Playfair-cipher/NetRexx/playfair-cipher.netrexx
Normal file
165
Task/Playfair-cipher/NetRexx/playfair-cipher.netrexx
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref symbols nobinary
|
||||
|
||||
-- input arguments:
|
||||
-- encipher/decipher IQ-switch key text
|
||||
-- encipher/decipher -
|
||||
-- a character E, D (default E; . is an alias for E)
|
||||
-- IQ-switch -
|
||||
-- a character I, Q (default I for I==J, Q for exclude Q; . is an alias for I)
|
||||
-- key -
|
||||
-- the cipher key - default plugh_xyzzy (really just PLUGHXYZ)
|
||||
-- text -
|
||||
-- the text to encipher/decipher
|
||||
|
||||
runSample(arg)
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method cipher(d_, km, digraphs) public static
|
||||
if d_.upper() = 'D' then d_ = -1 -- encode or decode adjustment
|
||||
else d_ = +1
|
||||
cipherText = ''
|
||||
loop dw = 1 to digraphs.words()
|
||||
-- process the digraphs one at a time
|
||||
digraph = digraphs.word(dw)
|
||||
cl = ''
|
||||
cr = ''
|
||||
-- get each letter from the digraph
|
||||
parse digraph dl +1 dr
|
||||
loop r_ = 1 to km[0] while (cl cr).words() < 4
|
||||
-- locate the row/col of each letter in the cipher matrix
|
||||
clx = km[r_].wordpos(dl)
|
||||
crx = km[r_].wordpos(dr)
|
||||
if clx > 0 then cl = r_ clx
|
||||
if crx > 0 then cr = r_ crx
|
||||
end r_
|
||||
|
||||
-- process the digraph's rows, columns or rectangles
|
||||
select
|
||||
when cl.word(1) = cr.word(1) then do
|
||||
-- a row
|
||||
rx = cl.word(1)
|
||||
clx = cl.word(2) + d_
|
||||
crx = cr.word(2) + d_
|
||||
if clx > 5 then clx = 1 -- wrap
|
||||
if crx > 5 then crx = 1
|
||||
if clx < 1 then clx = 5
|
||||
if crx < 1 then crx = 5
|
||||
cy = km[rx].word(clx) || km[rx].word(crx)
|
||||
cipherText = cipherText cy
|
||||
end
|
||||
when cl.word(2) = cr.word(2) then do
|
||||
-- a column
|
||||
cx = cl.word(2)
|
||||
rlx = cl.word(1) + d_
|
||||
rrx = cr.word(1) + d_
|
||||
if rlx > 5 then rlx = 1 -- wrap
|
||||
if rrx > 5 then rrx = 1
|
||||
if rlx < 1 then rlx = 5
|
||||
if rrx < 1 then rrx = 5
|
||||
cy = km[rlx].word(cx) || km[rrx].word(cx)
|
||||
cipherText = cipherText cy
|
||||
end
|
||||
otherwise do
|
||||
-- a rectangle
|
||||
r1 = cl.word(1)
|
||||
r2 = cr.word(1)
|
||||
cy = km[r1].word(cr.word(2)) || km[r2].word(cl.word(2))
|
||||
cipherText = cipherText cy
|
||||
end
|
||||
end
|
||||
end dw
|
||||
return cipherText.strip()
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method encipher(km, digraphs) public static
|
||||
return cipher('E', km, digraphs)
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method decipher(km, digraphs) public static
|
||||
return cipher('D', km, digraphs)
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method getDigraphs(text, IorQ, ED) private static
|
||||
a2z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
if ED.upper() \= 'D' then eks = 'X'
|
||||
else eks = ''
|
||||
tp = text.upper().translate('', a2z)
|
||||
text = text.upper().translate(' '.copies(tp.length()), tp).space(0)
|
||||
rtext = ''
|
||||
ll = ''
|
||||
|
||||
loop while text \= ''
|
||||
parse text lc +1 text
|
||||
if ll \= lc then rtext = rtext || lc
|
||||
else rtext = rtext || eks || lc
|
||||
ll = lc
|
||||
end
|
||||
|
||||
-- I == J or remove Q fixup
|
||||
if IorQ \= 'Q' then
|
||||
parse 'J I' IorQ sc .
|
||||
else
|
||||
sc = ''
|
||||
|
||||
rtext = rtext.changestr(IorQ, sc)
|
||||
if rtext.length() // 2 \= 0 then rtext = rtext || eks
|
||||
digraphs = ''
|
||||
loop while rtext \= ''
|
||||
parse rtext digraph +2 rtext
|
||||
digraphs = digraphs digraph
|
||||
end
|
||||
return digraphs.space()
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method getKey(key, IorQ) private static
|
||||
a2z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
kp = (key || a2z).upper()
|
||||
kr = ''
|
||||
loop while kp \= ''
|
||||
parse kp xx +1 kp
|
||||
if \xx.datatype('u') then iterate
|
||||
kr = kr xx
|
||||
kp = kp.changestr(xx, '')
|
||||
end
|
||||
|
||||
if IorQ = 'I' | IorQ = 'J' | IorQ = '' then
|
||||
kr = kr.changestr('J', '')
|
||||
else
|
||||
kr = kr.changestr('Q', '')
|
||||
|
||||
return kr.space()
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method getKeyMatrix(kr) private static
|
||||
km = ''
|
||||
loop r_ = 1 while kr \= ''
|
||||
parse kr kp +10 kr
|
||||
km[0] = r_
|
||||
km[r_] = kp
|
||||
end r_
|
||||
return km
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method runSample(arg) private static
|
||||
parse arg ciph IorQ key text
|
||||
if ciph = '' | ciph = '.' then ciph = 'E'
|
||||
if IorQ = '' | IorQ = '.' then IorQ = 'I'
|
||||
if key = '' | key = '.' then key = 'plugh_xyzzy'
|
||||
if text = '' | text = '.' then text = 'NetRexx; not just a programing language for kings & queens!'
|
||||
|
||||
kr = getKey(key.space(0), IorQ)
|
||||
km = getKeyMatrix(kr)
|
||||
|
||||
digraphs = getDigraphs(text, IorQ, ciph)
|
||||
-- fixup for a Q in the text when Q is excluded (substitute K for Q)
|
||||
if IorQ.upper = 'Q' then digraphs = digraphs.changestr('Q', 'K')
|
||||
if ciph = 'E' then say text
|
||||
say digraphs
|
||||
if ciph.upper() = 'E' then
|
||||
say encipher(km, digraphs)
|
||||
else
|
||||
say decipher(km, digraphs)
|
||||
|
||||
return
|
||||
99
Task/Playfair-cipher/Nim/playfair-cipher.nim
Normal file
99
Task/Playfair-cipher/Nim/playfair-cipher.nim
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
import pegs, strutils
|
||||
|
||||
type
|
||||
Position = tuple[x, y: int]
|
||||
Playfair = object
|
||||
positions: array['A'..'Z', Position]
|
||||
table: array[5, array[5, char]]
|
||||
|
||||
const None: Position = (-1, -1) # Default value for positions.
|
||||
|
||||
|
||||
proc initPlayfair(key: string; jti: bool): Playfair =
|
||||
|
||||
for item in result.positions.mitems: item = None
|
||||
|
||||
var alphabet = key & "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
alphabet = if jti: alphabet.replace('J', 'I')
|
||||
else: alphabet.replace("Q", "")
|
||||
|
||||
var k = 0
|
||||
for ch in alphabet:
|
||||
if result.positions[ch] == None:
|
||||
result.table[k div 5][k mod 5] = ch
|
||||
result.positions[ch] = (k mod 5, k div 5)
|
||||
inc k
|
||||
|
||||
|
||||
proc codec(playfair: Playfair; text: string; direction: int): string =
|
||||
|
||||
result.setLen(text.len)
|
||||
|
||||
for i in countup(0, text.high, 2):
|
||||
var
|
||||
(col1, row1) = playfair.positions[text[i]]
|
||||
(col2, row2) = playfair.positions[text[i + 1]]
|
||||
|
||||
if row1 == row2:
|
||||
col1 = (col1 + direction) mod 5
|
||||
col2 = (col2 + direction) mod 5
|
||||
elif col1 == col2:
|
||||
row1 = (row1 + direction) mod 5
|
||||
row2 = (row2 + direction) mod 5
|
||||
else:
|
||||
swap col1, col2
|
||||
|
||||
result[i] = playfair.table[row1][col1]
|
||||
result[i + 1] = playfair.table[row2][col2]
|
||||
|
||||
|
||||
proc encode(playfair: Playfair; text: string): string =
|
||||
var
|
||||
text = text
|
||||
i = 0
|
||||
|
||||
while i < text.len:
|
||||
if i == text.high:
|
||||
if (text.len and 1) != 0:
|
||||
text.add 'X'
|
||||
elif text[i] == text[i + 1]:
|
||||
text.insert("X", i + 1)
|
||||
inc i, 2
|
||||
|
||||
result = playfair.codec(text, 1)
|
||||
|
||||
|
||||
proc decode(playfair: Playfair; text: string): string =
|
||||
result = playfair.codec(text, 4)
|
||||
|
||||
|
||||
proc prompt(msg: string): string =
|
||||
stdout.write msg
|
||||
try:
|
||||
result = stdin.readLine()
|
||||
except EOFError:
|
||||
echo ""
|
||||
quit getCurrentExceptionMsg(), QuitFailure
|
||||
|
||||
|
||||
when isMainModule:
|
||||
|
||||
var key: string
|
||||
while key.len <= 6:
|
||||
key = prompt("Enter an encryption key (min letters 6): ").toUpperAscii().replace(peg"[^A-Z]")
|
||||
|
||||
var text: string
|
||||
while text.len == 0:
|
||||
text = prompt("Enter the message: ").toUpperAscii().replace(peg"[^A-Z]")
|
||||
|
||||
var answer: string
|
||||
while answer notin ["y", "n"]:
|
||||
answer = prompt("Replace J with I? y/n: ").toLowerAscii()
|
||||
let jti = (answer == "y")
|
||||
|
||||
let playfair = initPlayfair(key, jti)
|
||||
let enc = playfair.encode(text)
|
||||
let dec = playfair.decode(enc)
|
||||
|
||||
echo "Encoded message: ", enc
|
||||
echo "Decoded message: ", dec
|
||||
198
Task/Playfair-cipher/OoRexx/playfair-cipher.rexx
Normal file
198
Task/Playfair-cipher/OoRexx/playfair-cipher.rexx
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*---------------------------------------------------------------------
|
||||
* REXX program implements a PLAYFAIR cipher (encryption & decryption).
|
||||
* 11.11.2013 Walter Pachl revamped, for ooRexx, the REXX program
|
||||
* the logic of which was devised by Gerard Schildberger
|
||||
* Invoke as rexx pf O abcd efgh ( phrase to be processed
|
||||
* Defaults: 'Playfair example.'
|
||||
* J
|
||||
* 'Hide the gold in the tree stump'
|
||||
* Major changes: avoid language elements not allowed in ooRexx
|
||||
* show use of a.[expr1,expr2]
|
||||
* allow key to be more than one word
|
||||
* add restriction of using X or Q in text
|
||||
* 12.11.2013 change order of arguments
|
||||
* and comment the use of a.[expr1,expr2]
|
||||
* Program should run on all Rexxes that have changestr-bif
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Upper Version v
|
||||
oorexx=pos('OOREXX',v)>0
|
||||
|
||||
Parse Arg omit oldk '(' text
|
||||
If omit='' Then omit='J'
|
||||
If oldk='' Then oldk='Playfair example.'
|
||||
If text='' Then text='Hide the gold in the tree stump!!'
|
||||
|
||||
newkey=scrub(oldk,1)
|
||||
newtext=scrub(text)
|
||||
If newtext=='' Then Call err 'TEXT is empty or has no letters'
|
||||
If length(omit)\==1 Then Call err 'OMIT letter must be only one letter'
|
||||
If\datatype(omit,'M') Then Call err 'OMIT letter must be a Latin alphabet letter.'
|
||||
omit=translate(omit)
|
||||
cant='must not contain the "OMIT" character: ' omit
|
||||
If pos(omit,newtext)\==0 Then Call err 'TEXT' cant
|
||||
If pos(omit,newkey)\==0 Then Call err 'cipher key' cant
|
||||
abc='abcdefghijklmnopqrstuvwxyz'
|
||||
abcu=translate(abc) /* uppercase alphabet */
|
||||
abcx=space(translate(abcu,,omit),0) /*elide OMIT char from alphabet */
|
||||
xx='X' /* char used for double characters*/
|
||||
If omit==xx Then
|
||||
xx='Q'
|
||||
If pos(xx,newtext)>0 Then
|
||||
Call err 'Sorry,' xx 'is not allowed in text'
|
||||
If length(newkey)<3 Then
|
||||
Call err 'cipher key is too short, must be at least 3 different letters'
|
||||
abcx=space(translate(abcx,,newkey),0) /*remove any cipher characters */
|
||||
grid=newkey||abcx /* only first 25 chars are used*/
|
||||
Say 'old cipher key: ' strip(oldk)
|
||||
padl=14+2
|
||||
pad=left('',padl)
|
||||
Say 'new cipher key: ' newkey
|
||||
padx=left('',padl,"-")'Playfair'
|
||||
Say ' omit char: ' omit /* [?] lowercase of double char. */
|
||||
Say ' double char: ' xx
|
||||
lxx=translate(xx,abc,abcu)
|
||||
Say ' original text: ' strip(text)/* [?] doubled version of Lxx. */
|
||||
Call show 'cleansed',newtext
|
||||
lxxlxx=lxx||lxx
|
||||
n=0 /* number of grid characters used.*/
|
||||
Do row=1 For 5 /* build array of individual cells*/
|
||||
Do col=1 For 5
|
||||
n=n+1
|
||||
a.row.col=substr(grid,n,1)
|
||||
If row==1 Then
|
||||
a.0.col=a.1.col
|
||||
If col==5 Then Do
|
||||
a.row.6=a.row.1
|
||||
a.row.0=a.row.5
|
||||
End
|
||||
If row==5 Then Do
|
||||
a.6.col=a.1.col
|
||||
a.0.col=a.5.col
|
||||
End
|
||||
End
|
||||
End
|
||||
|
||||
etext=playfair(newtext,1)
|
||||
Call show 'encrypted',etext
|
||||
ptext=playfair(etext,-1)
|
||||
Call show 'plain',ptext
|
||||
qtext=changestr(xx||xx,ptext,lxx) /*change doubled doublechar-?sing*/
|
||||
qtext=changestr(lxx||xx,qtext,lxxlxx) /*change Xx --? lowercase dblChar*/
|
||||
qtext=space(translate(qtext,,xx),0) /*remove char used for "doubles."*/
|
||||
qtext=translate(qtext) /*reinstate the use of upperchars*/
|
||||
Call show 'decoded',qtext
|
||||
Say ' original text: ' newtext /* ·· and show the original text.*/
|
||||
Say ''
|
||||
Exit
|
||||
|
||||
playfair:
|
||||
/*---------------------------------------------------------------------
|
||||
* encode (e=1) or decode (e=-1) the given text (t) using the grid
|
||||
*--------------------------------------------------------------------*/
|
||||
Arg t,e
|
||||
d=''
|
||||
If e=1 Then Do
|
||||
Do k=1 By 1 Until c=''
|
||||
c=substr(t,k,1)
|
||||
If substr(t,k+1,1)==c Then
|
||||
t=left(t,k)||lxx||substr(t,k+1)
|
||||
End
|
||||
End
|
||||
t=translate(t)
|
||||
Do j=1 By 2 To length(t)
|
||||
c2=strip(substr(t,j,2))
|
||||
If length(c2)==1 Then
|
||||
c2=c2||xx /* append X or Q char, rule 1*/
|
||||
Call LR
|
||||
Select
|
||||
/*- This could/should be used on ooRexx -------------------------
|
||||
When rowl==rowr Then c2=a.[rowl,coll+e]a.[rowr,colr+e] /*rule 2*/
|
||||
When coll==colr Then c2=a.[rowl+e,coll]a.[rowr+e,colr] /*rule 3*/
|
||||
*--------------------------------------------------------------*/
|
||||
When rowl==rowr Then c2=aa(rowl,coll+e)aa(rowr,colr+e) /*rule 2*/
|
||||
When coll==colr Then c2=aa(rowl+e,coll)aa(rowr+e,colr) /*rule 3*/
|
||||
Otherwise c2=a.rowl.colr||a.rowr.coll /*rule 4*/
|
||||
End
|
||||
d=d||c2
|
||||
End
|
||||
Return d
|
||||
|
||||
aa:
|
||||
/*---------------------------------------------------------------------
|
||||
* ooRexx allows to use a.[rowl,coll+e]
|
||||
* this function can be removed when ooRexx syntax is used to access a.
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Arg xrow,xcol
|
||||
Return a.xrow.xcol
|
||||
|
||||
err:
|
||||
/*---------------------------------------------------------------------
|
||||
* Exit with an error message
|
||||
*--------------------------------------------------------------------*/
|
||||
Say
|
||||
Say '***error!***' arg(1)
|
||||
Say
|
||||
Exit 13
|
||||
|
||||
lr:
|
||||
/*---------------------------------------------------------------------
|
||||
* get grid positions of the 2 characters
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Value rowcol(left(c2,1)) with rowl coll
|
||||
Parse Value rowcol(right(c2,1)) with rowr colr
|
||||
Return
|
||||
|
||||
rowcol: procedure Expose grid
|
||||
/*---------------------------------------------------------------------
|
||||
* compute row and column of the given character in the 5x5 grid
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Arg c
|
||||
p=pos(c,grid)
|
||||
col=(p-1)//5+1
|
||||
row=(4+p)%5
|
||||
Return row col
|
||||
|
||||
show:
|
||||
/*---------------------------------------------------------------------
|
||||
* Show heading and text
|
||||
*--------------------------------------------------------------------*/
|
||||
Arg,y
|
||||
Say
|
||||
Say right(arg(1) 'text: ',padl) digram(arg(2))
|
||||
result=space(arg(2),0)
|
||||
If arg(1)='decoded' Then Do
|
||||
result=strip(result,'T',xx)
|
||||
End
|
||||
Say pad result
|
||||
Return
|
||||
|
||||
scrub: Procedure
|
||||
/*---------------------------------------------------------------------
|
||||
* Remove all non-letters from the given string, uppercase letters
|
||||
* and, if unique=1 remove duplicates
|
||||
* 'aB + c1Bb' -> 'ABCBB' or 'ABC', respectively
|
||||
*--------------------------------------------------------------------*/
|
||||
Arg xxx,unique /* ARG caps all args */
|
||||
d=''
|
||||
used.=0
|
||||
Do While xxx<>''
|
||||
Parse Var xxx c +1 xxx
|
||||
If datatype(c,'U') Then
|
||||
If (unique=1 & pos(c,d)=0) |,
|
||||
unique<>1 Then
|
||||
d=d||c
|
||||
End
|
||||
Return d
|
||||
|
||||
digram: Procedure
|
||||
/*---------------------------------------------------------------------
|
||||
* Return the given string as character pairs separated by blanks
|
||||
* 'ABCDEF' -> 'AB CD EF'
|
||||
* 'ABCDE' -> 'AB CD E'
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse Arg x
|
||||
d=''
|
||||
Do j=1 By 2 To length(x)
|
||||
d=d||substr(x,j,2)' '
|
||||
End
|
||||
Return strip(d)
|
||||
72
Task/Playfair-cipher/Perl/playfair-cipher.pl
Normal file
72
Task/Playfair-cipher/Perl/playfair-cipher.pl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
use Math::Cartesian::Product;
|
||||
|
||||
# Pregenerate all forward and reverse translations
|
||||
sub playfair {
|
||||
our($key,$from) = @_;
|
||||
$from //= 'J';
|
||||
our $to = $from eq 'J' ? 'I' : '';
|
||||
my(%ENC,%DEC,%seen,@m);
|
||||
|
||||
sub canon {
|
||||
my($str) = @_;
|
||||
$str =~ s/[^[:alpha:]]//g;
|
||||
$str =~ s/$from/$to/gi;
|
||||
uc $str;
|
||||
}
|
||||
|
||||
my @uniq = grep { ! $seen{$_}++ } split '', canon($key . join '', 'A'..'Z');
|
||||
while (@uniq) { push @m, [splice @uniq, 0, 5] }
|
||||
|
||||
# Map pairs in same row.
|
||||
for my $r (@m) {
|
||||
for my $x (cartesian {@_} [0..4], [0..4]) {
|
||||
my($i,$j) = @$x;
|
||||
next if $i == $j;
|
||||
$ENC{ @$r[$i] . @$r[$j] } = @$r[($i+1)%5] . @$r[($j+1)%5];
|
||||
}
|
||||
}
|
||||
|
||||
# Map pairs in same column.
|
||||
for my $c (0..4) {
|
||||
my @c = map { @$_[$c] } @m;
|
||||
for my $x (cartesian {@_} [0..4], [0..4]) {
|
||||
my($i,$j) = @$x;
|
||||
next if $i == $j;
|
||||
$ENC{ $c[$i] . $c[$j] } = $c[($i+1)%5] . $c[($j+1)%5];
|
||||
}
|
||||
}
|
||||
|
||||
# Map pairs with cross-connections.
|
||||
for my $x (cartesian {@_} [0..4], [0..4], [0..4], [0..4]) {
|
||||
my($i1,$j1,$i2,$j2) = @$x;
|
||||
next if $i1 == $i2 or $j1 == $j2;
|
||||
$ENC{ $m[$i1][$j1] . $m[$i2][$j2] } = $m[$i1][$j2] . $m[$i2][$j1];
|
||||
}
|
||||
|
||||
# Generate reverse translations.
|
||||
while (my ($k, $v) = each %ENC) { $DEC{$v} = $k }
|
||||
|
||||
# Return code-refs for encoding/decoding routines
|
||||
return
|
||||
sub { my($red) = @_; # encode
|
||||
my $str = canon($red);
|
||||
|
||||
my @list;
|
||||
while ($str =~ /(.)(?(?=\1)|(.?))/g) {
|
||||
push @list, substr($str,$-[0], $-[2] ? 2 : 1);
|
||||
}
|
||||
join ' ', map { length($_)==1 ? $ENC{$_.'X'} : $ENC{$_} } @list;
|
||||
},
|
||||
sub { my($black) = @_; # decode
|
||||
join ' ', map { $DEC{$_} } canon($black) =~ /../g;
|
||||
}
|
||||
}
|
||||
|
||||
my($encode,$decode) = playfair('Playfair example');
|
||||
|
||||
my $orig = "Hide the gold in...the TREESTUMP!!!";
|
||||
my $black = &$encode($orig);
|
||||
my $red = &$decode($black);
|
||||
print " orig:\t$orig\n";
|
||||
print "black:\t$black\n";
|
||||
print " red:\t$red\n";
|
||||
115
Task/Playfair-cipher/Phix/playfair-cipher.phix
Normal file
115
Task/Playfair-cipher/Phix/playfair-cipher.phix
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">keyword</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Playfair example"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">option</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'Q'</span> <span style="color: #000080;font-style:italic;">-- ignore Q
|
||||
-- option = 'J' -- replace J with I</span>
|
||||
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">table</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">findchar</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">build_table</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">table</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">),</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">findchar</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">findchar</span><span style="color: #0000FF;">[</span><span style="color: #000000;">option</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000080;font-style:italic;">-- (note any (J/Q) in keyword are simply ignored)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">alphabet</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">keyword</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">&</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'Z'</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">findchar</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">table</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span>
|
||||
<span style="color: #000000;">findchar</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #000000;">j</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">6</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">6</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- table filled</span>
|
||||
<span style="color: #000000;">j</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
<span style="color: #000000;">build_table</span><span style="color: #0000FF;">()</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">clean_text</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">plaintext</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- get rid of any non-letters and insert X between duplicate letters
|
||||
--</span>
|
||||
<span style="color: #000000;">plaintext</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">cleantext</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">prevChar</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">nextChar</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">plaintext</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">nextChar</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">nextChar</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'Z'</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">nextChar</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'Q'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">option</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'Q'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">nextChar</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'J'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">option</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'J'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">nextChar</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'I'</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">nextChar</span><span style="color: #0000FF;">=</span><span style="color: #000000;">prevChar</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">cleantext</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'X'</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">cleantext</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">nextChar</span>
|
||||
<span style="color: #000000;">prevChar</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nextChar</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">odd</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cleantext</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000080;font-style:italic;">-- dangling letter at end so add another letter to complete digraph</span>
|
||||
<span style="color: #000000;">cleantext</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cleantext</span><span style="color: #0000FF;">[$]=</span><span style="color: #008000;">'X'</span><span style="color: #0000FF;">?</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">:</span><span style="color: #008000;">'X'</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">cleantext</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">remove_x</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'X'</span>
|
||||
<span style="color: #008080;">and</span> <span style="color: #0000FF;">((</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">and</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">or</span>
|
||||
<span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">' '</span> <span style="color: #008080;">and</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]))</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'_'</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">text</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">playfair</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">text</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- text may be the plaintext or the encoded version
|
||||
-- step is 2 for plaintext, 3 for encoded(/skip spaces)
|
||||
-- d is {2,3,4,5,1} instead of mod(+1,5), or
|
||||
-- {5,1,2,3,4} -- -1
|
||||
--</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #000000;">step</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">row1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">findchar</span><span style="color: #0000FF;">[</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">row2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">findchar</span><span style="color: #0000FF;">[</span><span style="color: #000000;">text</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" "</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">row1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">row2</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">col1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">col1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">col2</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">col1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">col2</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">row1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">row2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">d</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row2</span><span style="color: #0000FF;">]}</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">col1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">col2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col1</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">table</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">col1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">&</span> <span style="color: #000000;">table</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row2</span><span style="color: #0000FF;">][</span><span style="color: #000000;">col2</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">plaintext</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">playfair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">clean_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">ciphertext</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000080;font-style:italic;">-- ciphertext includes spaces we need to skip, hence by 3</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">remove_x</span><span style="color: #0000FF;">(</span><span style="color: #000000;">playfair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ciphertext</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Playfair keyword : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">keyword</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Option: J=I or no Q (J/Q) : %s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">option</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The table to be used is :\n\n%s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">table</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">plaintext</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Hide the gold...in the TREESTUMP!!!!"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">encoded</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">decoded</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">encoded</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"The plain text : %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">plaintext</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Encoded text is : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">encoded</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Decoded text is : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">decoded</span><span style="color: #0000FF;">})</span>
|
||||
<!--
|
||||
62
Task/Playfair-cipher/Python/playfair-cipher.py
Normal file
62
Task/Playfair-cipher/Python/playfair-cipher.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
from string import ascii_uppercase
|
||||
from itertools import product
|
||||
from re import findall
|
||||
|
||||
def uniq(seq):
|
||||
seen = {}
|
||||
return [seen.setdefault(x, x) for x in seq if x not in seen]
|
||||
|
||||
def partition(seq, n):
|
||||
return [seq[i : i + n] for i in xrange(0, len(seq), n)]
|
||||
|
||||
|
||||
"""Instantiate a specific encoder/decoder."""
|
||||
def playfair(key, from_ = 'J', to = None):
|
||||
if to is None:
|
||||
to = 'I' if from_ == 'J' else ''
|
||||
|
||||
def canonicalize(s):
|
||||
return filter(str.isupper, s.upper()).replace(from_, to)
|
||||
|
||||
# Build 5x5 matrix.
|
||||
m = partition(uniq(canonicalize(key + ascii_uppercase)), 5)
|
||||
|
||||
# Pregenerate all forward translations.
|
||||
enc = {}
|
||||
|
||||
# Map pairs in same row.
|
||||
for row in m:
|
||||
for i, j in product(xrange(5), repeat=2):
|
||||
if i != j:
|
||||
enc[row[i] + row[j]] = row[(i + 1) % 5] + row[(j + 1) % 5]
|
||||
|
||||
# Map pairs in same column.
|
||||
for c in zip(*m):
|
||||
for i, j in product(xrange(5), repeat=2):
|
||||
if i != j:
|
||||
enc[c[i] + c[j]] = c[(i + 1) % 5] + c[(j + 1) % 5]
|
||||
|
||||
# Map pairs with cross-connections.
|
||||
for i1, j1, i2, j2 in product(xrange(5), repeat=4):
|
||||
if i1 != i2 and j1 != j2:
|
||||
enc[m[i1][j1] + m[i2][j2]] = m[i1][j2] + m[i2][j1]
|
||||
|
||||
# Generate reverse translations.
|
||||
dec = dict((v, k) for k, v in enc.iteritems())
|
||||
|
||||
def sub_enc(txt):
|
||||
lst = findall(r"(.)(?:(?!\1)(.))?", canonicalize(txt))
|
||||
return " ".join(enc[a + (b if b else 'X')] for a, b in lst)
|
||||
|
||||
def sub_dec(encoded):
|
||||
return " ".join(dec[p] for p in partition(canonicalize(encoded), 2))
|
||||
|
||||
return sub_enc, sub_dec
|
||||
|
||||
|
||||
(encode, decode) = playfair("Playfair example")
|
||||
orig = "Hide the gold in...the TREESTUMP!!!"
|
||||
print "Original:", orig
|
||||
enc = encode(orig)
|
||||
print "Encoded:", enc
|
||||
print "Decoded:", decode(enc)
|
||||
88
Task/Playfair-cipher/REXX/playfair-cipher.rexx
Normal file
88
Task/Playfair-cipher/REXX/playfair-cipher.rexx
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*REXX program implements a PLAYFAIR cipher (encryption and decryption). */
|
||||
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU= @abc /*literals for lower and upper ABC's.*/
|
||||
parse arg omit key '(' text /*TEXT is the phrase to be used. */
|
||||
oldKey= key /*save the old key. */
|
||||
if key =='' | key ==',' then do; key= 'Playfair example.'
|
||||
oldKey= key " ◄───using the default."
|
||||
end
|
||||
if omit=='' | omit==',' then omit= 'J' /*the "omitted" character string. */
|
||||
if text='' then text= 'Hide the gold in the tree stump!!' /*default.*/
|
||||
upper omit @abcU /*uppercase OMIT characters & alphabet.*/
|
||||
@cant= 'can''t contain the "OMIT" character: ' omit /*literal used in error text.*/
|
||||
@uchars= 'unique characters.' /*a literal used below in an error msg.*/
|
||||
newKey = scrub(key, 1) /*scrub old cipher key ──► newKey */
|
||||
newText= scrub(text ) /* " " text ──► newText */
|
||||
if newText=='' then call err 'TEXT is empty or has no letters.'
|
||||
if length(omit)\==1 then call err 'OMIT letter must be only one letter.'
|
||||
if \datatype(omit, 'M') then call err 'OMIT letter must be a Latin alphabet letter.'
|
||||
if pos(omit, newText)\==0 then call err 'TEXT' @cant
|
||||
if pos(omit, newKey) \==0 then call err 'cipher key' @cant
|
||||
fill= space( translate(@abcU, , omit), 0) /*elide OMIT characters from alphabet. */
|
||||
xx= 'X' /*character used for double characters.*/
|
||||
if omit==xx then xx= 'Q' /* " " " " " */
|
||||
if length(newKey)<3 then call err 'cipher key is too short, must be ≥ 3' @uchars
|
||||
fill= space( translate(fill, , newKey), 0) /*remove any cipher characters. */
|
||||
grid= newKey || fill /*only first 25 characters are used. */
|
||||
say 'old cipher key: ' strip(oldKey)
|
||||
say 'new cipher key: ' newKey
|
||||
say ' omit char: ' omit
|
||||
say ' double char: ' xx
|
||||
say ' original text: ' strip(text)
|
||||
padL= 14 + 2
|
||||
call show 'cleansed', newText
|
||||
#= 0 /*number of grid characters used. */
|
||||
do row =1 for 5 /*build array of individual cells. */
|
||||
do col=1 for 5; #= # + 1; @.row.col= substr(grid, #, 1)
|
||||
if row==1 then @.0.col= @.1.col
|
||||
if col==5 then do; @.row.6= @.row.1; @.row.0= @.row.5; end
|
||||
if row==5 then do; @.6.col= @.1.col; @.0.col= @.5.col; end
|
||||
end /*col*/
|
||||
end /*row*/
|
||||
pad = left('', padL)
|
||||
padX= left('', padL, "═")'Playfair'
|
||||
Lxx = translate(xx, @abc, @abcU) /* [↓] lowercase of double character. */
|
||||
LxxLxx= Lxx || Lxx /* [↓] doubled version of Lxx. */
|
||||
eText= .Playfair(newText, 1); call show 'encrypted' , eText
|
||||
pText= .Playfair(eText ); call show 'plain' , pText
|
||||
qText= changestr(xx || xx, pText, Lxx) /*change doubled doublechar ──► single.*/
|
||||
qText= changestr(Lxx || xx, qText, LxxLxx) /*change xx ──► lowercase dblCharacter*/
|
||||
qText= space( translate( qText, , xx), 0) /*remove character used for "doubles". */
|
||||
upper qText /*reinstate the use of upper characters*/
|
||||
if length(qText)\==length(pText) then call show 'possible', qText
|
||||
say ' original text: ' newText; say /*··· and also show the original text. */
|
||||
if qtext==newText then say padx 'encryption──► decryption──► encryption worked.'
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
@@: parse arg Xrow,Xcol; return @.Xrow.Xcol
|
||||
err: say; say '***error!***' arg(1); say; exit 13
|
||||
LR: rowL= row(left(__, 1)); colL= _; rowR= row(right(__,1)); colR= _; return length(__)
|
||||
row: ?= pos(arg(1), grid); _= (?-1) // 5 + 1; return (4+?) % 5
|
||||
show: arg ,y; say; say right(arg(1) 'text: ',padL) digram(y); say pad space(y, 0); return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
.Playfair: arg T,encrypt; i= -1; if encrypt==1 then i= 1; $=
|
||||
do k=1 while i==1; _= substr(T, k, 1); if _==' ' then leave
|
||||
if _==substr(T, k+1, 1) then T= left(T, k) || Lxx || substr(T, k + 1)
|
||||
end /*k*/
|
||||
upper T
|
||||
do j=1 by 2 to length(T); __= strip( substr(T, j, 2) )
|
||||
if LR()==1 then __= __ || xx; call LR /*append X or Q char, rule 1*/
|
||||
select /*rule*/
|
||||
when rowL==rowR then __= @@(rowL, colL+i)@@(rowR, colR+i) /*2*/
|
||||
when colL==colR then __= @@(rowL+i, colL )@@(rowR+i, colR) /*3*/
|
||||
otherwise __= @@(rowL, colR )@@(rowR, colL) /*4*/
|
||||
end /*select*/
|
||||
$= $ || __
|
||||
end /*j*/
|
||||
return $
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
digram: procedure; parse arg x,,$; do j=1 by 2 to length(x)
|
||||
$= $ || substr(x, j, 2)' '
|
||||
end /*j*/
|
||||
return strip($)
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
scrub: procedure; arg xxx,unique; xxx= space(xxx, 0) /*ARG capitalizes all args*/
|
||||
$=; do j=1 for length(xxx); _= substr(xxx, j, 1)
|
||||
if unique==1 then if pos(_, $)\==0 then iterate /*is unique?*/
|
||||
if datatype(_, 'M') then $= $ || _ /*only use Latin letters. */
|
||||
end /*j*/
|
||||
return $
|
||||
63
Task/Playfair-cipher/Raku/playfair-cipher.raku
Normal file
63
Task/Playfair-cipher/Raku/playfair-cipher.raku
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# 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.unique.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
|
||||
sub enc($red) {
|
||||
my @list = canon($red).comb(/(.) (.?) <?{ $1 ne $0 }>/);
|
||||
~@list.map: { .chars == 1 ?? %ENC{$_~'X'} !! %ENC{$_} }
|
||||
},
|
||||
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";
|
||||
54
Task/Playfair-cipher/Ruby/playfair-cipher.rb
Normal file
54
Task/Playfair-cipher/Ruby/playfair-cipher.rb
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
class Playfair
|
||||
Size = 5
|
||||
def initialize(key, missing)
|
||||
@missing = missing.upcase
|
||||
alphabet = ('A'..'Z').to_a.join.upcase.delete(@missing).split''
|
||||
extended = key.upcase.gsub(/[^A-Z]/,'').split('') + alphabet
|
||||
grid = extended.uniq[0...Size*Size].each_slice(Size).to_a
|
||||
coords = {}
|
||||
grid.each_with_index do |row, i|
|
||||
row.each_with_index do |letter, j|
|
||||
coords[letter] = [i,j]
|
||||
end
|
||||
end
|
||||
@encode = {}
|
||||
alphabet.product(alphabet).reject { |a,b| a==b }.each do |a, b|
|
||||
i1, j1 = coords[a]
|
||||
i2, j2 = coords[b]
|
||||
if i1 == i2 then
|
||||
j1 = (j1 + 1) % Size
|
||||
j2 = (j2 + 1) % Size
|
||||
elsif j1 == j2 then
|
||||
i1 = (i1 + 1) % Size
|
||||
i2 = (i2 + 1) % Size
|
||||
else
|
||||
j1, j2 = j2, j1
|
||||
end
|
||||
@encode["#{a}#{b}"] = "#{grid[i1][j1]}#{grid[i2][j2]}"
|
||||
@decode = @encode.invert
|
||||
end
|
||||
end
|
||||
|
||||
def encode(plaintext)
|
||||
plain = plaintext.upcase.gsub(/[^A-Z]/,'')
|
||||
if @missing == 'J' then
|
||||
plain = plain.gsub(/J/, 'I')
|
||||
else
|
||||
plain = plain.gsub(@missing, 'X')
|
||||
end
|
||||
plain = plain.gsub(/(.)\1/, '\1X\1')
|
||||
if plain.length % 2 == 1 then
|
||||
plain += 'X'
|
||||
end
|
||||
return plain.upcase.split('').each_slice(2).map do |pair|
|
||||
@encode[pair.join]
|
||||
end.join.split('').each_slice(5).map{|s|s.join}.join(' ')
|
||||
end
|
||||
|
||||
def decode(ciphertext)
|
||||
cipher = ciphertext.upcase.gsub(/[^A-Z]/,'')
|
||||
return cipher.upcase.split('').each_slice(2).map do |pair|
|
||||
@decode[pair.join]
|
||||
end.join.split('').each_slice(5).map{|s|s.join}.join(' ')
|
||||
end
|
||||
end
|
||||
313
Task/Playfair-cipher/SQL/playfair-cipher.sql
Normal file
313
Task/Playfair-cipher/SQL/playfair-cipher.sql
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
--Clean up previous run
|
||||
IF EXISTS (SELECT *
|
||||
FROM SYS.TYPES
|
||||
WHERE NAME = 'FairPlayTable')
|
||||
DROP TYPE FAIRPLAYTABLE
|
||||
|
||||
--Set Types
|
||||
CREATE TYPE FAIRPLAYTABLE AS TABLE (LETTER VARCHAR(1), COLID INT, ROWID INT)
|
||||
|
||||
GO
|
||||
|
||||
--Configuration Variables
|
||||
DECLARE @KEYWORD VARCHAR(25) = 'CHARLES' --Keyword for encryption
|
||||
DECLARE @INPUT VARCHAR(MAX) = 'Testing Seeconqz' --Word to be encrypted
|
||||
DECLARE @Q INT = 0 -- Q removed?
|
||||
DECLARE @ENCRYPT INT = 1 --Encrypt?
|
||||
--Setup Variables
|
||||
DECLARE @WORDS TABLE
|
||||
(
|
||||
WORD_PRE VARCHAR(2),
|
||||
WORD_POST VARCHAR(2)
|
||||
)
|
||||
DECLARE @T_TABLE FAIRPLAYTABLE
|
||||
DECLARE @NEXTLETTER CHAR(1)
|
||||
DECLARE @WORD VARCHAR(2),
|
||||
@COL1 INT,
|
||||
@COL2 INT,
|
||||
@ROW1 INT,
|
||||
@ROW2 INT,
|
||||
@TMP INT
|
||||
DECLARE @SQL NVARCHAR(MAX) = '',
|
||||
@COUNTER INT = 1,
|
||||
@I INT = 1
|
||||
DECLARE @COUNTER_2 INT = 1
|
||||
|
||||
SET @INPUT = REPLACE(@INPUT, ' ', '')
|
||||
SET @KEYWORD = UPPER(@KEYWORD)
|
||||
|
||||
DECLARE @USEDLETTERS VARCHAR(MAX) = ''
|
||||
DECLARE @TESTWORDS VARCHAR(2),
|
||||
@A INT = 0
|
||||
|
||||
WHILE @COUNTER_2 <= 5
|
||||
BEGIN
|
||||
WHILE @COUNTER <= 5
|
||||
BEGIN
|
||||
IF LEN(@KEYWORD) > 0
|
||||
BEGIN
|
||||
SET @NEXTLETTER = LEFT(@KEYWORD, 1)
|
||||
SET @KEYWORD = RIGHT(@KEYWORD, LEN(@KEYWORD) - 1)
|
||||
|
||||
IF CHARINDEX(@NEXTLETTER, @USEDLETTERS) = 0
|
||||
BEGIN
|
||||
INSERT INTO @T_TABLE
|
||||
SELECT @NEXTLETTER,
|
||||
@COUNTER,
|
||||
@COUNTER_2
|
||||
|
||||
SET @COUNTER = @COUNTER + 1
|
||||
SET @USEDLETTERS = @USEDLETTERS + @NEXTLETTER
|
||||
END
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
WHILE 1 = 1
|
||||
BEGIN
|
||||
IF CHARINDEX(CHAR(64 + @I), @USEDLETTERS) = 0
|
||||
AND NOT ( CHAR(64 + @I) = 'Q'
|
||||
AND @Q = 1 )
|
||||
AND NOT ( @Q = 0
|
||||
AND CHAR(64 + @I) = 'J' )
|
||||
BEGIN
|
||||
SET @NEXTLETTER = CHAR(64 + @I)
|
||||
SET @USEDLETTERS = @USEDLETTERS + CHAR(64 + @I)
|
||||
SET @I = @I + 1
|
||||
|
||||
BREAK
|
||||
END
|
||||
|
||||
SET @I = @I + 1
|
||||
END
|
||||
|
||||
-- SELECT 1 AS [T]
|
||||
--BREAK
|
||||
INSERT INTO @T_TABLE
|
||||
SELECT @NEXTLETTER,
|
||||
@COUNTER,
|
||||
@COUNTER_2
|
||||
|
||||
SET @COUNTER = @COUNTER + 1
|
||||
END
|
||||
END
|
||||
|
||||
SET @COUNTER_2 = @COUNTER_2 + 1
|
||||
SET @COUNTER = 1
|
||||
END
|
||||
|
||||
--Split word into Digraphs
|
||||
WHILE @A < 1
|
||||
BEGIN
|
||||
SET @TESTWORDS = UPPER(LEFT(@INPUT, 2))
|
||||
|
||||
IF LEN(@TESTWORDS) = 1
|
||||
BEGIN
|
||||
SET @TESTWORDS = @TESTWORDS + 'X'
|
||||
SET @A = 1
|
||||
END
|
||||
ELSE IF RIGHT(@TESTWORDS, 1) = LEFT(@TESTWORDS, 1)
|
||||
BEGIN
|
||||
SET @TESTWORDS = RIGHT(@TESTWORDS, 1) + 'X'
|
||||
SET @INPUT = RIGHT(@INPUT, LEN(@INPUT) - 1)
|
||||
END
|
||||
ELSE
|
||||
SET @INPUT = RIGHT(@INPUT, LEN(@INPUT) - 2)
|
||||
|
||||
IF LEN(@INPUT) = 0
|
||||
SET @A = 1
|
||||
|
||||
INSERT @WORDS
|
||||
SELECT @TESTWORDS,
|
||||
''
|
||||
END
|
||||
|
||||
--Start Encryption
|
||||
IF @ENCRYPT = 1
|
||||
BEGIN
|
||||
--Loop through Digraphs amd encrypt
|
||||
DECLARE WORDS_LOOP CURSOR LOCAL FORWARD_ONLY FOR
|
||||
SELECT WORD_PRE
|
||||
FROM @WORDS
|
||||
FOR UPDATE OF WORD_POST
|
||||
|
||||
OPEN WORDS_LOOP
|
||||
|
||||
FETCH NEXT FROM WORDS_LOOP INTO @WORD
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
--Find letter positions
|
||||
SET @ROW1 = (SELECT ROWID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = LEFT(@WORD, 1))
|
||||
SET @ROW2 = (SELECT ROWID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = RIGHT(@WORD, 1))
|
||||
SET @COL1 = (SELECT COLID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = LEFT(@WORD, 1))
|
||||
SET @COL2 = (SELECT COLID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = RIGHT(@WORD, 1))
|
||||
|
||||
--Move positions according to encryption rules
|
||||
IF @COL1 = @COL2
|
||||
BEGIN
|
||||
SET @ROW1 = @ROW1 + 1
|
||||
SET @ROW2 = @ROW2 + 1
|
||||
--select 'row'
|
||||
END
|
||||
ELSE IF @ROW1 = @ROW2
|
||||
BEGIN
|
||||
SET @COL1 = @COL1 + 1
|
||||
SET @COL2 = @COL2 + 1
|
||||
--select 'col'
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
SET @TMP = @COL2
|
||||
SET @COL2 = @COL1
|
||||
SET @COL1 = @TMP
|
||||
--select 'reg'
|
||||
END
|
||||
|
||||
IF @ROW1 = 6
|
||||
SET @ROW1 = 1
|
||||
|
||||
IF @ROW2 = 6
|
||||
SET @ROW2 = 1
|
||||
|
||||
IF @COL1 = 6
|
||||
SET @COL1 = 1
|
||||
|
||||
IF @COL2 = 6
|
||||
SET @COL2 = 1
|
||||
|
||||
--Find encrypted letters by positions
|
||||
UPDATE @WORDS
|
||||
SET WORD_POST = (SELECT (SELECT LETTER
|
||||
FROM @T_TABLE
|
||||
WHERE ROWID = @ROW1
|
||||
AND COLID = @COL1)
|
||||
+ (SELECT LETTER
|
||||
FROM @T_TABLE
|
||||
WHERE COLID = @COL2
|
||||
AND ROWID = @ROW2))
|
||||
WHERE WORD_PRE = @WORD
|
||||
|
||||
FETCH NEXT FROM WORDS_LOOP INTO @WORD
|
||||
END
|
||||
|
||||
CLOSE WORDS_LOOP
|
||||
|
||||
DEALLOCATE WORDS_LOOP
|
||||
END
|
||||
--Start Decryption
|
||||
ELSE
|
||||
BEGIN
|
||||
--Loop through Digraphs amd decrypt
|
||||
DECLARE WORDS_LOOP CURSOR LOCAL FORWARD_ONLY FOR
|
||||
SELECT WORD_PRE
|
||||
FROM @WORDS
|
||||
FOR UPDATE OF WORD_POST
|
||||
|
||||
OPEN WORDS_LOOP
|
||||
|
||||
FETCH NEXT FROM WORDS_LOOP INTO @WORD
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
--Find letter positions
|
||||
SET @ROW1 = (SELECT ROWID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = LEFT(@WORD, 1))
|
||||
SET @ROW2 = (SELECT ROWID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = RIGHT(@WORD, 1))
|
||||
SET @COL1 = (SELECT COLID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = LEFT(@WORD, 1))
|
||||
SET @COL2 = (SELECT COLID
|
||||
FROM @T_TABLE
|
||||
WHERE LETTER = RIGHT(@WORD, 1))
|
||||
|
||||
--Move positions according to encryption rules
|
||||
IF @COL1 = @COL2
|
||||
BEGIN
|
||||
SET @ROW1 = @ROW1 - 1
|
||||
SET @ROW2 = @ROW2 - 1
|
||||
--select 'row'
|
||||
END
|
||||
ELSE IF @ROW1 = @ROW2
|
||||
BEGIN
|
||||
SET @COL1 = @COL1 - 1
|
||||
SET @COL2 = @COL2 - 1
|
||||
--select 'col'
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
SET @TMP = @COL2
|
||||
SET @COL2 = @COL1
|
||||
SET @COL1 = @TMP
|
||||
--select 'reg'
|
||||
END
|
||||
|
||||
IF @ROW1 = 0
|
||||
SET @ROW1 = 5
|
||||
|
||||
IF @ROW2 = 0
|
||||
SET @ROW2 = 5
|
||||
|
||||
IF @COL1 = 0
|
||||
SET @COL1 = 5
|
||||
|
||||
IF @COL2 = 0
|
||||
SET @COL2 = 5
|
||||
|
||||
--Find decrypted letters by positions
|
||||
UPDATE @WORDS
|
||||
SET WORD_POST = (SELECT (SELECT LETTER
|
||||
FROM @T_TABLE
|
||||
WHERE ROWID = @ROW1
|
||||
AND COLID = @COL1)
|
||||
+ (SELECT LETTER
|
||||
FROM @T_TABLE
|
||||
WHERE COLID = @COL2
|
||||
AND ROWID = @ROW2))
|
||||
WHERE WORD_PRE = @WORD
|
||||
|
||||
FETCH NEXT FROM WORDS_LOOP INTO @WORD
|
||||
END
|
||||
|
||||
CLOSE WORDS_LOOP
|
||||
|
||||
DEALLOCATE WORDS_LOOP
|
||||
END
|
||||
|
||||
--Output
|
||||
DECLARE WORDS CURSOR LOCAL FAST_FORWARD FOR
|
||||
SELECT WORD_POST
|
||||
FROM @WORDS
|
||||
|
||||
OPEN WORDS
|
||||
|
||||
FETCH NEXT FROM WORDS INTO @WORD
|
||||
|
||||
WHILE @@FETCH_STATUS = 0
|
||||
BEGIN
|
||||
SET @SQL = @SQL + @WORD + ' '
|
||||
|
||||
FETCH NEXT FROM WORDS INTO @WORD
|
||||
END
|
||||
|
||||
CLOSE WORDS
|
||||
|
||||
DEALLOCATE WORDS
|
||||
|
||||
SELECT @SQL
|
||||
|
||||
--Cleanup
|
||||
IF EXISTS (SELECT *
|
||||
FROM SYS.TYPES
|
||||
WHERE NAME = 'FairPlayTable')
|
||||
DROP TYPE FAIRPLAYTABLE
|
||||
59
Task/Playfair-cipher/Sidef/playfair-cipher.sidef
Normal file
59
Task/Playfair-cipher/Sidef/playfair-cipher.sidef
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
func playfair(key, from = 'J', to = (from == 'J' ? 'I' : '')) {
|
||||
|
||||
func canon(str) {
|
||||
str.gsub(/[^[:alpha:]]/, '').uc.gsub(from, to)
|
||||
}
|
||||
|
||||
var m = canon(key + ('A'..'Z' -> join)).chars.uniq.slices(5)
|
||||
|
||||
var :ENC = gather {
|
||||
m.each { |r|
|
||||
for i,j in (^r ~X ^r) {
|
||||
i == j && next
|
||||
take(Pair("#{r[i]}#{r[j]}", "#{r[(i+1)%5]}#{r[(j+1)%5]}"))
|
||||
}
|
||||
}
|
||||
|
||||
^5 -> each { |k|
|
||||
var c = m.map {|a| a[k] }
|
||||
for i,j in (^c ~X ^c) {
|
||||
i == j && next
|
||||
take(Pair("#{c[i]}#{c[j]}", "#{c[(i+1)%5]}#{c[(j+1)%5]}"))
|
||||
}
|
||||
}
|
||||
|
||||
cartesian([^5, ^5, ^5, ^5], {|i1,j1,i2,j2|
|
||||
i1 == i2 && next
|
||||
j1 == j2 && next
|
||||
take(Pair("#{m[i1][j1]}#{m[i2][j2]}", "#{m[i1][j2]}#{m[i2][j1]}"))
|
||||
})
|
||||
}.map { (.key, .value) }...
|
||||
|
||||
var DEC = ENC.flip
|
||||
|
||||
func enc(red) {
|
||||
gather {
|
||||
var str = canon(red)
|
||||
while (var m = (str =~ /(.)(?(?=\1)|(.?))/g)) {
|
||||
take("#{m[0]}#{m[1] == '' ? 'X' : m[1]}")
|
||||
}
|
||||
}.map { ENC{_} }.join(' ')
|
||||
}
|
||||
|
||||
func dec(black) {
|
||||
canon(black).split(2).map { DEC{_} }.join(' ')
|
||||
}
|
||||
|
||||
return(enc, dec)
|
||||
}
|
||||
|
||||
var (encode, decode) = playfair('Playfair example')
|
||||
|
||||
var orig = "Hide the gold in...the TREESTUMP!!!"
|
||||
say " orig:\t#{orig}"
|
||||
|
||||
var black = encode(orig)
|
||||
say "black:\t#{black}"
|
||||
|
||||
var red = decode(black)
|
||||
say " red:\t#{red}"
|
||||
86
Task/Playfair-cipher/Tcl/playfair-cipher-1.tcl
Normal file
86
Task/Playfair-cipher/Tcl/playfair-cipher-1.tcl
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package require TclOO
|
||||
|
||||
oo::class create Playfair {
|
||||
variable grid lookup excluder
|
||||
constructor {{keyword "PLAYFAIR EXAMPLE"} {exclude "J"}} {
|
||||
# Tweaking according to exact operation mode
|
||||
if {$exclude eq "J"} {
|
||||
set excluder "J I"
|
||||
} else {
|
||||
set excluder [list $exclude ""]
|
||||
}
|
||||
|
||||
# Clean up the keyword source
|
||||
set keys [my Clean [append keyword "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]]
|
||||
|
||||
# Generate the encoding grid
|
||||
set grid [lrepeat 5 [lrepeat 5 ""]]
|
||||
set idx -1
|
||||
for {set i 0} {$i < 5} {incr i} {for {set j 0} {$j < 5} {} {
|
||||
if {![info exist lookup([set c [lindex $keys [incr idx]]])]} {
|
||||
lset grid $i $j $c
|
||||
set lookup($c) [list $i $j]
|
||||
incr j
|
||||
}
|
||||
}}
|
||||
|
||||
# Sanity check
|
||||
if {[array size lookup] != 25} {
|
||||
error "failed to build encoding table correctly"
|
||||
}
|
||||
}
|
||||
|
||||
# Worker to apply a consistent cleanup/split rule
|
||||
method Clean {str} {
|
||||
set str [string map $excluder [string toupper $str]]
|
||||
split [regsub -all {[^A-Z]} $str ""] ""
|
||||
}
|
||||
|
||||
# These public methods are implemented by a single non-public method
|
||||
forward encode my Transform 1
|
||||
forward decode my Transform -1
|
||||
|
||||
# The application of the Playfair cypher transform
|
||||
method Transform {direction message} {
|
||||
# Split message into true digraphs
|
||||
foreach c [my Clean $message] {
|
||||
if {![info exists lookup($c)]} continue
|
||||
if {![info exists c0]} {
|
||||
set c0 $c
|
||||
} else {
|
||||
if {$c0 ne $c} {
|
||||
lappend digraphs $c0 $c
|
||||
unset c0
|
||||
} else {
|
||||
lappend digraphs $c0 "X"
|
||||
set c0 $c
|
||||
}
|
||||
}
|
||||
}
|
||||
if {[info exists c0]} {
|
||||
lappend digraphs $c0 "Z"
|
||||
}
|
||||
|
||||
# Encode the digraphs
|
||||
set result ""
|
||||
foreach {a b} $digraphs {
|
||||
lassign $lookup($a) ai aj
|
||||
lassign $lookup($b) bi bj
|
||||
if {$ai == $bi} {
|
||||
set aj [expr {($aj + $direction) % 5}]
|
||||
set bj [expr {($bj + $direction) % 5}]
|
||||
} elseif {$aj == $bj} {
|
||||
set ai [expr {($ai + $direction) % 5}]
|
||||
set bi [expr {($bi + $direction) % 5}]
|
||||
} else {
|
||||
set tmp $aj
|
||||
set aj $bj
|
||||
set bj $tmp
|
||||
}
|
||||
lappend result [lindex $grid $ai $aj][lindex $grid $bi $bj]
|
||||
}
|
||||
|
||||
# Real use would be: return [join $result ""]
|
||||
return $result
|
||||
}
|
||||
}
|
||||
7
Task/Playfair-cipher/Tcl/playfair-cipher-2.tcl
Normal file
7
Task/Playfair-cipher/Tcl/playfair-cipher-2.tcl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Playfair create cypher "Playfair Example"
|
||||
set plaintext "Hide the gold in...the TREESTUMP!!!"
|
||||
set encoded [cypher encode $plaintext]
|
||||
set decoded [cypher decode $encoded]
|
||||
puts "Original: $plaintext"
|
||||
puts "Encoded: $encoded"
|
||||
puts "Decoded: $decoded"
|
||||
189
Task/Playfair-cipher/V-(Vlang)/playfair-cipher.v
Normal file
189
Task/Playfair-cipher/V-(Vlang)/playfair-cipher.v
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
import os
|
||||
import strings
|
||||
type PlayfairOption = int
|
||||
|
||||
const (
|
||||
no_q = 0
|
||||
i_equals_j = 1
|
||||
)
|
||||
|
||||
struct Playfair {
|
||||
mut:
|
||||
keyword string
|
||||
pfo PlayfairOption
|
||||
table [5][5]u8
|
||||
}
|
||||
|
||||
fn (mut p Playfair) init() {
|
||||
// Build table.
|
||||
mut used := [26]bool{} // all elements false
|
||||
if p.pfo == no_q {
|
||||
used[16] = true // Q used
|
||||
} else {
|
||||
used[9] = true // J used
|
||||
}
|
||||
alphabet := p.keyword.to_upper() + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
for i, j, k := 0, 0, 0; k < alphabet.len; k++ {
|
||||
c := alphabet[k]
|
||||
if c < 'A'[0] || c > 'Z'[0] {
|
||||
continue
|
||||
}
|
||||
d := int(c - 65)
|
||||
if !used[d] {
|
||||
p.table[i][j] = c
|
||||
used[d] = true
|
||||
j++
|
||||
if j == 5 {
|
||||
i++
|
||||
if i == 5 {
|
||||
break // table has been filled
|
||||
}
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (p Playfair) get_clean_text(pt string) string {
|
||||
// Ensure everything is upper case.
|
||||
plain_text := pt.to_upper()
|
||||
// Get rid of any non-letters and insert X between duplicate letters.
|
||||
mut clean_text := strings.new_builder(128)
|
||||
// Safe to assume null u8 won't be present in plain_text.
|
||||
mut prev_byte := `\000`
|
||||
for i in 0..plain_text.len {
|
||||
mut next_byte := plain_text[i]
|
||||
// It appears that Q should be omitted altogether if NO_Q option is specified;
|
||||
// we assume so anyway.
|
||||
if next_byte < 'A'[0] || next_byte > 'Z'[0] || (next_byte == 'Q'[0] && p.pfo == no_q) {
|
||||
continue
|
||||
}
|
||||
// If i_equals_j option specified, replace J with I.
|
||||
if next_byte == 'J'[0] && p.pfo == i_equals_j {
|
||||
next_byte = 'I'[0]
|
||||
}
|
||||
if next_byte != prev_byte {
|
||||
clean_text.write_u8(next_byte)
|
||||
} else {
|
||||
clean_text.write_u8('X'[0])
|
||||
clean_text.write_u8(next_byte)
|
||||
}
|
||||
prev_byte = next_byte
|
||||
}
|
||||
l := clean_text.len
|
||||
if l%2 == 1 {
|
||||
// Dangling letter at end so add another letter to complete digram.
|
||||
if clean_text.str()[l-1] != 'X'[0] {
|
||||
clean_text.write_u8('X'[0])
|
||||
} else {
|
||||
clean_text.write_u8('Z'[0])
|
||||
}
|
||||
}
|
||||
return clean_text.str()
|
||||
}
|
||||
|
||||
fn (p Playfair) find_byte(c u8) (int, int) {
|
||||
for i in 0..5 {
|
||||
for j in 0..5 {
|
||||
if p.table[i][j] == c {
|
||||
return i, j
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1, -1
|
||||
}
|
||||
|
||||
fn (p Playfair) encode(plain_text string) string {
|
||||
clean_text := p.get_clean_text(plain_text)
|
||||
mut cipher_text := strings.new_builder(128)
|
||||
l := clean_text.len
|
||||
for i := 0; i < l; i += 2 {
|
||||
row1, col1 := p.find_byte(clean_text[i])
|
||||
row2, col2 := p.find_byte(clean_text[i+1])
|
||||
if row1 == row2{
|
||||
cipher_text.write_u8(p.table[row1][(col1+1)%5])
|
||||
cipher_text.write_u8(p.table[row2][(col2+1)%5])
|
||||
} else if col1 == col2{
|
||||
cipher_text.write_u8(p.table[(row1+1)%5][col1])
|
||||
cipher_text.write_u8(p.table[(row2+1)%5][col2])
|
||||
} else {
|
||||
cipher_text.write_u8(p.table[row1][col2])
|
||||
cipher_text.write_u8(p.table[row2][col1])
|
||||
}
|
||||
if i < l-1 {
|
||||
cipher_text.write_u8(' '[0])
|
||||
}
|
||||
}
|
||||
return cipher_text.str()
|
||||
}
|
||||
|
||||
fn (p Playfair) decode(cipher_text string) string {
|
||||
mut decoded_text := strings.new_builder(128)
|
||||
l := cipher_text.len
|
||||
// cipher_text will include spaces so we need to skip them.
|
||||
for i := 0; i < l; i += 3 {
|
||||
row1, col1 := p.find_byte(cipher_text[i])
|
||||
row2, col2 := p.find_byte(cipher_text[i+1])
|
||||
if row1 == row2 {
|
||||
mut temp := 4
|
||||
if col1 > 0 {
|
||||
temp = col1 - 1
|
||||
}
|
||||
decoded_text.write_u8(p.table[row1][temp])
|
||||
temp = 4
|
||||
if col2 > 0 {
|
||||
temp = col2 - 1
|
||||
}
|
||||
decoded_text.write_u8(p.table[row2][temp])
|
||||
} else if col1 == col2 {
|
||||
mut temp := 4
|
||||
if row1 > 0 {
|
||||
temp = row1 - 1
|
||||
}
|
||||
decoded_text.write_u8(p.table[temp][col1])
|
||||
temp = 4
|
||||
if row2 > 0 {
|
||||
temp = row2 - 1
|
||||
}
|
||||
decoded_text.write_u8(p.table[temp][col2])
|
||||
} else {
|
||||
decoded_text.write_u8(p.table[row1][col2])
|
||||
decoded_text.write_u8(p.table[row2][col1])
|
||||
}
|
||||
if i < l-1 {
|
||||
decoded_text.write_u8(' '[0])
|
||||
}
|
||||
}
|
||||
return decoded_text.str()
|
||||
}
|
||||
|
||||
fn (p Playfair) print_table() {
|
||||
println("The table to be used is :\n")
|
||||
for i in 0..5 {
|
||||
for j in 0..5 {
|
||||
print("${p.table[i][j].ascii_str()} ")
|
||||
}
|
||||
println('')
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
keyword := os.input("Enter Playfair keyword : ")
|
||||
mut ignore_q := ''
|
||||
for ignore_q != "y" && ignore_q != "n" {
|
||||
ignore_q = os.input("Ignore Q when building table y/n : ").to_lower()
|
||||
}
|
||||
mut pfo := no_q
|
||||
if ignore_q == "n" {
|
||||
pfo = i_equals_j
|
||||
}
|
||||
mut table := [5][5]u8{}
|
||||
mut pf := Playfair{keyword, pfo, table}
|
||||
pf.init()
|
||||
pf.print_table()
|
||||
plain_text := os.input("\nEnter plain text : ")
|
||||
encoded_text := pf.encode(plain_text)
|
||||
println("\nEncoded text is : $encoded_text")
|
||||
decoded_text := pf.decode(encoded_text)
|
||||
println("Deccoded text is : $decoded_text")
|
||||
}
|
||||
207
Task/Playfair-cipher/VBA/playfair-cipher.vba
Normal file
207
Task/Playfair-cipher/VBA/playfair-cipher.vba
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
Option Explicit
|
||||
|
||||
Private Type Adress
|
||||
Row As Integer
|
||||
Column As Integer
|
||||
End Type
|
||||
|
||||
Private myTable() As String
|
||||
|
||||
Sub Main()
|
||||
Dim keyw As String, boolQ As Boolean, text As String, test As Long
|
||||
Dim res As String
|
||||
keyw = InputBox("Enter your keyword : ", "KeyWord", "Playfair example")
|
||||
If keyw = "" Then GoTo ErrorHand
|
||||
Debug.Print "Enter your keyword : " & keyw
|
||||
boolQ = MsgBox("Ignore Q when buiding table y/n : ", vbYesNo) = vbYes
|
||||
Debug.Print "Ignore Q when buiding table y/n : " & IIf(boolQ, "Y", "N")
|
||||
Debug.Print ""
|
||||
Debug.Print "Table : "
|
||||
myTable = CreateTable(keyw, boolQ)
|
||||
On Error GoTo ErrorHand
|
||||
test = UBound(myTable)
|
||||
On Error GoTo 0
|
||||
text = InputBox("Enter your text", "Encode", "hide the gold in the TRRE stump")
|
||||
If text = "" Then GoTo ErrorHand
|
||||
Debug.Print ""
|
||||
Debug.Print "Text to encode : " & text
|
||||
Debug.Print "-------------------------------------------------"
|
||||
res = Encode(text)
|
||||
Debug.Print "Encoded text is : " & res
|
||||
res = Decode(res)
|
||||
Debug.Print "Decoded text is : " & res
|
||||
text = InputBox("Enter your text", "Encode", "hide the gold in the TREE stump")
|
||||
If text = "" Then GoTo ErrorHand
|
||||
Debug.Print ""
|
||||
Debug.Print "Text to encode : " & text
|
||||
Debug.Print "-------------------------------------------------"
|
||||
res = Encode(text)
|
||||
Debug.Print "Encoded text is : " & res
|
||||
res = Decode(res)
|
||||
Debug.Print "Decoded text is : " & res
|
||||
Exit Sub
|
||||
ErrorHand:
|
||||
Debug.Print "error"
|
||||
End Sub
|
||||
|
||||
Private Function CreateTable(strKeyword As String, Q As Boolean) As String()
|
||||
Dim r As Integer, c As Integer, temp(1 To 5, 1 To 5) As String, t, cpt As Integer
|
||||
Dim strT As String, coll As New Collection
|
||||
Dim s As String
|
||||
|
||||
strKeyword = UCase(Replace(strKeyword, " ", ""))
|
||||
If Q Then
|
||||
If InStr(strKeyword, "J") > 0 Then
|
||||
Debug.Print "Your keyword isn't available with your choice : Not Q (==> J) !"
|
||||
Exit Function
|
||||
End If
|
||||
Else
|
||||
If InStr(strKeyword, "Q") > 0 Then
|
||||
Debug.Print "Your keyword isn't available with your choice : Q (==> Not J) !"
|
||||
Exit Function
|
||||
End If
|
||||
End If
|
||||
strT = IIf(Not Q, "ABCDEFGHIKLMNOPQRSTUVWXYZ", "ABCDEFGHIJKLMNOPRSTUVWXYZ")
|
||||
t = Split(StrConv(strKeyword, vbUnicode), Chr(0))
|
||||
For c = LBound(t) To UBound(t) - 1
|
||||
strT = Replace(strT, t(c), "")
|
||||
On Error Resume Next
|
||||
coll.Add t(c), t(c)
|
||||
On Error GoTo 0
|
||||
Next
|
||||
strKeyword = vbNullString
|
||||
For c = 1 To coll.Count
|
||||
strKeyword = strKeyword & coll(c)
|
||||
Next
|
||||
t = Split(StrConv(strKeyword & strT, vbUnicode), Chr(0))
|
||||
c = 1: r = 1
|
||||
For cpt = LBound(t) To UBound(t) - 1
|
||||
temp(r, c) = t(cpt)
|
||||
s = s & " " & t(cpt)
|
||||
c = c + 1
|
||||
If c = 6 Then c = 1: r = r + 1: Debug.Print " " & s: s = ""
|
||||
Next
|
||||
CreateTable = temp
|
||||
End Function
|
||||
|
||||
Private Function Encode(s As String) As String
|
||||
Dim i&, t() As String, cpt&
|
||||
s = UCase(Replace(s, " ", ""))
|
||||
'insert "X"
|
||||
For i = 1 To Len(s) - 1
|
||||
If Mid(s, i, 1) = Mid(s, i + 1, 1) Then s = Left(s, i) & "X" & Right(s, Len(s) - i)
|
||||
Next
|
||||
'Do the pairs
|
||||
For i = 1 To Len(s) Step 2
|
||||
ReDim Preserve t(cpt)
|
||||
t(cpt) = Mid(s, i, 2)
|
||||
cpt = cpt + 1
|
||||
Next i
|
||||
If Len(t(UBound(t))) = 1 Then t(UBound(t)) = t(UBound(t)) & "X"
|
||||
Debug.Print "[the pairs : " & Join(t, " ") & "]"
|
||||
'swap the pairs
|
||||
For i = LBound(t) To UBound(t)
|
||||
t(i) = SwapPairsEncoding(t(i))
|
||||
Next
|
||||
Encode = Join(t, " ")
|
||||
End Function
|
||||
|
||||
Private Function SwapPairsEncoding(s As String) As String
|
||||
Dim r As Integer, c As Integer, d1 As String, d2 As String, Flag As Boolean
|
||||
Dim addD1 As Adress, addD2 As Adress, resD1 As Adress, resD2 As Adress
|
||||
d1 = Left(s, 1): d2 = Right(s, 1)
|
||||
For r = 1 To 5
|
||||
For c = 1 To 5
|
||||
If d1 = myTable(r, c) Then addD1.Row = r: addD1.Column = c
|
||||
If d2 = myTable(r, c) Then addD2.Row = r: addD2.Column = c
|
||||
If addD1.Row <> 0 And addD2.Row <> 0 Then Flag = True: Exit For
|
||||
Next
|
||||
If Flag Then Exit For
|
||||
Next
|
||||
Select Case True
|
||||
Case addD1.Row = addD2.Row And addD1.Column <> addD2.Column
|
||||
'same row, different columns
|
||||
resD1.Column = IIf(addD1.Column + 1 = 6, 1, addD1.Column + 1)
|
||||
resD2.Column = IIf(addD2.Column + 1 = 6, 1, addD2.Column + 1)
|
||||
SwapPairsEncoding = myTable(addD1.Row, resD1.Column) & myTable(addD2.Row, resD2.Column)
|
||||
Case addD1.Row <> addD2.Row And addD1.Column = addD2.Column
|
||||
'same columns, different rows
|
||||
resD1.Row = IIf(addD1.Row + 1 = 6, 1, addD1.Row + 1)
|
||||
resD2.Row = IIf(addD2.Row + 1 = 6, 1, addD2.Row + 1)
|
||||
SwapPairsEncoding = myTable(resD1.Row, addD1.Column) & myTable(resD2.Row, addD2.Column)
|
||||
Case addD1.Row <> addD2.Row And addD1.Column <> addD2.Column
|
||||
'different rows, different columns
|
||||
resD1.Row = addD1.Row
|
||||
resD2.Row = addD2.Row
|
||||
resD1.Column = addD2.Column
|
||||
resD2.Column = addD1.Column
|
||||
SwapPairsEncoding = myTable(resD1.Row, resD1.Column) & myTable(resD2.Row, resD2.Column)
|
||||
End Select
|
||||
End Function
|
||||
|
||||
Private Function Decode(s As String) As String
|
||||
Dim t, i&, j&, e&
|
||||
t = Split(s, " ")
|
||||
e = UBound(t) - 1
|
||||
'swap the pairs
|
||||
For i = LBound(t) To UBound(t)
|
||||
t(i) = SwapPairsDecoding(CStr(t(i)))
|
||||
Next
|
||||
'remove "X"
|
||||
For i = LBound(t) To e
|
||||
If Right(t(i), 1) = "X" And Left(t(i), 1) = Left(t(i + 1), 1) Then
|
||||
t(i) = Left(t(i), 1) & Left(t(i + 1), 1)
|
||||
For j = i + 1 To UBound(t) - 1
|
||||
t(j) = Right(t(j), 1) & Left(t(j + 1), 1)
|
||||
Next j
|
||||
If Right(t(j), 1) = "X" Then
|
||||
ReDim Preserve t(j - 1)
|
||||
Else
|
||||
t(j) = Right(t(j), 1) & "X"
|
||||
End If
|
||||
ElseIf Left(t(i + 1), 1) = "X" And Right(t(i), 1) = Right(t(i + 1), 1) Then
|
||||
For j = i + 1 To UBound(t) - 1
|
||||
t(j) = Right(t(j), 1) & Left(t(j + 1), 1)
|
||||
Next j
|
||||
If Right(t(j), 1) = "X" Then
|
||||
ReDim Preserve t(j - 1)
|
||||
Else
|
||||
t(j) = Right(t(j), 1) & "X"
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
Decode = Join(t, " ")
|
||||
End Function
|
||||
|
||||
Private Function SwapPairsDecoding(s As String) As String
|
||||
Dim r As Integer, c As Integer, d1 As String, d2 As String, Flag As Boolean
|
||||
Dim addD1 As Adress, addD2 As Adress, resD1 As Adress, resD2 As Adress
|
||||
d1 = Left(s, 1): d2 = Right(s, 1)
|
||||
For r = 1 To 5
|
||||
For c = 1 To 5
|
||||
If d1 = myTable(r, c) Then addD1.Row = r: addD1.Column = c
|
||||
If d2 = myTable(r, c) Then addD2.Row = r: addD2.Column = c
|
||||
If addD1.Row <> 0 And addD2.Row <> 0 Then Flag = True: Exit For
|
||||
Next
|
||||
If Flag Then Exit For
|
||||
Next
|
||||
Select Case True
|
||||
Case addD1.Row = addD2.Row And addD1.Column <> addD2.Column
|
||||
'same row, different columns
|
||||
resD1.Column = IIf(addD1.Column - 1 = 0, 5, addD1.Column - 1)
|
||||
resD2.Column = IIf(addD2.Column - 1 = 0, 5, addD2.Column - 1)
|
||||
SwapPairsDecoding = myTable(addD1.Row, resD1.Column) & myTable(addD2.Row, resD2.Column)
|
||||
Case addD1.Row <> addD2.Row And addD1.Column = addD2.Column
|
||||
'same columns, different rows
|
||||
resD1.Row = IIf(addD1.Row - 1 = 0, 5, addD1.Row - 1)
|
||||
resD2.Row = IIf(addD2.Row - 1 = 0, 5, addD2.Row - 1)
|
||||
SwapPairsDecoding = myTable(resD1.Row, addD1.Column) & myTable(resD2.Row, addD2.Column)
|
||||
Case addD1.Row <> addD2.Row And addD1.Column <> addD2.Column
|
||||
'different rows, different columns
|
||||
resD1.Row = addD1.Row
|
||||
resD2.Row = addD2.Row
|
||||
resD1.Column = addD2.Column
|
||||
resD2.Column = addD1.Column
|
||||
SwapPairsDecoding = myTable(resD1.Row, resD1.Column) & myTable(resD2.Row, resD2.Column)
|
||||
End Select
|
||||
End Function
|
||||
135
Task/Playfair-cipher/Wren/playfair-cipher.wren
Normal file
135
Task/Playfair-cipher/Wren/playfair-cipher.wren
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
import "/dynamic" for Enum
|
||||
import "/str" for Str, Char
|
||||
import "/iterate" for Stepped
|
||||
import "/ioutil" for Input
|
||||
|
||||
var PlayfairOption = Enum.create("PlayfairOption", ["NO_Q", "I_EQUALS_J"])
|
||||
|
||||
class Playfair {
|
||||
construct new(keyword, pfo) {
|
||||
_pfo = pfo
|
||||
// build_table
|
||||
_table = List.filled(5, null)
|
||||
for (i in 0..4) _table[i] = List.filled(5, "\0") // 5 * 5 char list
|
||||
var used = List.filled(26, false)
|
||||
if (_pfo == PlayfairOption.NO_Q) {
|
||||
used[16] = true // Q used
|
||||
} else {
|
||||
used[9] = true // J used
|
||||
}
|
||||
var alphabet = Str.upper(keyword) + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
var i = 0
|
||||
var j = 0
|
||||
for (k in 0...alphabet.count) {
|
||||
var c = alphabet[k]
|
||||
if (Char.isAsciiUpper(c)) {
|
||||
var d = c.bytes[0] - 65
|
||||
if (!used[d]) {
|
||||
_table[i][j] = c
|
||||
used[d] = true
|
||||
j = j + 1
|
||||
if (j == 5) {
|
||||
i = i + 1
|
||||
if (i == 5) break // table has been filled
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getCleanText_(plainText) {
|
||||
var plainText2 = Str.upper(plainText) // ensure everything is upper case
|
||||
// get rid of any non-letters and insert X between duplicate letters
|
||||
var cleanText = ""
|
||||
var prevChar = "\0" // safe to assume null character won't be present in plainText
|
||||
for (i in 0...plainText2.count) {
|
||||
var nextChar = plainText2[i]
|
||||
// It appears that Q should be omitted altogether if NO_Q option is specified - we assume so anyway
|
||||
if (Char.isAsciiUpper(nextChar) && (nextChar != "Q" || _pfo != PlayfairOption.NO_Q)) {
|
||||
// If I_EQUALS_J option specified, replace J with I
|
||||
if (nextChar == "J" && _pfo == PlayfairOption.I_EQUALS_J) nextChar = "I"
|
||||
if (nextChar != prevChar) {
|
||||
cleanText = cleanText + nextChar
|
||||
} else {
|
||||
cleanText = cleanText + "X" + nextChar
|
||||
}
|
||||
prevChar = nextChar
|
||||
}
|
||||
}
|
||||
var len = cleanText.count
|
||||
if (len % 2 == 1) { // dangling letter at end so add another letter to complete digram
|
||||
if (cleanText[-1] != "X") {
|
||||
cleanText = cleanText + "X"
|
||||
} else {
|
||||
cleanText = cleanText + "Z"
|
||||
}
|
||||
}
|
||||
return cleanText
|
||||
}
|
||||
|
||||
findChar_(c) {
|
||||
for (i in 0..4) {
|
||||
for (j in 0..4) if (_table[i][j] == c) return [i, j]
|
||||
}
|
||||
return [-1, -1]
|
||||
}
|
||||
|
||||
encode(plainText) {
|
||||
var cleanText = getCleanText_(plainText)
|
||||
var cipherText = ""
|
||||
var length = cleanText.count
|
||||
for (i in Stepped.new(0...length, 2)) {
|
||||
var pair = findChar_(cleanText[i])
|
||||
var row1 = pair[0]
|
||||
var col1 = pair[1]
|
||||
pair = findChar_(cleanText[i + 1])
|
||||
var row2 = pair[0]
|
||||
var col2 = pair[1]
|
||||
cipherText = cipherText +
|
||||
((row1 == row2) ? _table[row1][(col1 + 1) % 5] +_table[row2][(col2 + 1) % 5] :
|
||||
(col1 == col2) ? _table[(row1 + 1) % 5][col1] +_table[(row2 + 1) % 5][col2] :
|
||||
_table[row1][col2] +_table[row2][col1])
|
||||
if (i < length - 1) cipherText = cipherText + " "
|
||||
}
|
||||
return cipherText
|
||||
}
|
||||
|
||||
decode(cipherText) {
|
||||
var decodedText = ""
|
||||
var length = cipherText.count
|
||||
for (i in Stepped.new(0...length, 3)) { // cipherText will include spaces so we need to skip them
|
||||
var pair = findChar_(cipherText[i])
|
||||
var row1 = pair[0]
|
||||
var col1 = pair[1]
|
||||
pair = findChar_(cipherText[i + 1])
|
||||
var row2 = pair[0]
|
||||
var col2 = pair[1]
|
||||
decodedText = decodedText +
|
||||
((row1 == row2) ? _table[row1][(col1 > 0) ? col1-1 : 4] +_table[row2][(col2 > 0) ? col2-1 : 4] :
|
||||
(col1 == col2) ? _table[(row1 > 0) ? row1-1 : 4][col1] +_table[(row2 > 0) ? row2-1 : 4][col2] :
|
||||
_table[row1][col2] +_table[row2][col1])
|
||||
if (i < length - 1) decodedText = decodedText + " "
|
||||
}
|
||||
return decodedText
|
||||
}
|
||||
|
||||
printTable() {
|
||||
System.print("The_table to be used is :\n")
|
||||
for (i in 0..4) {
|
||||
for (j in 0..4) System.write(_table[i][j] + " ")
|
||||
System.print()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var keyword = Input.text("Enter Playfair keyword : ", 1)
|
||||
var ignoreQ = Str.lower(Input.option("Ignore Q when building_table y/n : ", "yYnN"))
|
||||
var pfo = (ignoreQ == "y") ? PlayfairOption.NO_Q : PlayfairOption.I_EQUALS_J
|
||||
var playfair = Playfair.new(keyword, pfo)
|
||||
playfair.printTable()
|
||||
var plainText = Input.text("\nEnter plain text : ")
|
||||
var encodedText = playfair.encode(plainText)
|
||||
System.print("\nEncoded text is : %(encodedText)")
|
||||
var decodedText = playfair.decode(encodedText)
|
||||
System.print("Decoded text is : %(decodedText)")
|
||||
5
Task/Playfair-cipher/Zkl/playfair-cipher-1.zkl
Normal file
5
Task/Playfair-cipher/Zkl/playfair-cipher-1.zkl
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fcn genKeyTable(key,deadChr){ // deadChr=="Q" or "J"
|
||||
deadChr=deadChr.toUpper();
|
||||
key=key.toUpper().unique() - " " - deadChr;
|
||||
return(key + (["A".."Z"].pump(String) - deadChr - key), deadChr);
|
||||
}
|
||||
24
Task/Playfair-cipher/Zkl/playfair-cipher-2.zkl
Normal file
24
Task/Playfair-cipher/Zkl/playfair-cipher-2.zkl
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
fcn playfair(text,keytable){ // text is a-z only
|
||||
keyTable,deadChr:=keytable;
|
||||
text=text.toUpper();
|
||||
text-=text - keyTable; // remove unencodable characters
|
||||
if(deadChr=="Q") text-=deadChr; else text=text.replace("J","I");
|
||||
|
||||
text=text.pump(String,T(Void.Read,1,False),
|
||||
fcn(a,b=""){ if(a==b) a+"X"+b else a+b });
|
||||
if(text.len().isOdd) text+="Z";
|
||||
|
||||
row:='wrap(c){ keyTable.index(c)/5 };
|
||||
col:='wrap(c){ keyTable.index(c)%5 };
|
||||
ltrRight:='wrap(c){ keyTable[(keyTable.index(c) + 1)%25] };
|
||||
ltrBelow:='wrap(c){ keyTable[(keyTable.index(c) + 5)%25] };
|
||||
ltrAt:='wrap(r,c) { keyTable[r*5 + c] };
|
||||
|
||||
text.pump(String, Void.Read, //-->digraph
|
||||
'wrap(a,b){
|
||||
if((ra:=row(a))==(rb:=row(b))) return(ltrRight(a) + ltrRight(b));
|
||||
if((ca:=col(a))==(cb:=col(b))) return(ltrBelow(a) + ltrBelow(b));
|
||||
return(ltrAt(ra,cb) + ltrAt(rb,ca));
|
||||
})
|
||||
.pump(String,Void.Read,"".create.fp(" ")).strip(); // insert blanks
|
||||
}
|
||||
16
Task/Playfair-cipher/Zkl/playfair-cipher-3.zkl
Normal file
16
Task/Playfair-cipher/Zkl/playfair-cipher-3.zkl
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
fcn decodePF(text,keyTable){
|
||||
keyTable,_=keyTable;
|
||||
text-=" ";
|
||||
row:='wrap(c){ keyTable.index(c)/5 };
|
||||
col:='wrap(c){ keyTable.index(c)%5 };
|
||||
ltrLeft:='wrap(c){ keyTable[(keyTable.index(c) - 1)%25] };
|
||||
ltrUp:='wrap(c){ n:=keyTable.index(c) - 5; if(n<0)n+=25; keyTable[n%25] };
|
||||
ltrAt:='wrap(r,c){ keyTable[r*5 + c] };
|
||||
text.pump(String,Void.Read, //-->digraph
|
||||
'wrap(a,b){
|
||||
if((ra:=row(a))==(rb:=row(b))) return(ltrLeft(a) + ltrLeft(b));
|
||||
if((ca:=col(a))==(cb:=col(b))) return(ltrUp(a) + ltrUp(b));
|
||||
return(ltrAt(ra,cb) + ltrAt(rb,ca));
|
||||
})
|
||||
.pump(String,Void.Read,"".create.fp(" ")).strip(); // insert blanks
|
||||
}
|
||||
6
Task/Playfair-cipher/Zkl/playfair-cipher-4.zkl
Normal file
6
Task/Playfair-cipher/Zkl/playfair-cipher-4.zkl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
msg:="Hide the gold in the tree stump!!!";
|
||||
keyTable:=genKeyTable("playfair example");
|
||||
msg.println();
|
||||
e:=playfair(msg,keyTable); e.println();
|
||||
decodePF(e,keyTable).println();
|
||||
playfair("XX",keyTable).println() : decodePF(_,keyTable).println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue