Bifid cipher: Difference between revisions

15,776 bytes added ,  1 month ago
 
(15 intermediate revisions by 8 users not shown)
Line 279:
ENCRYPTED: QDFVQLBFJSAPLAE.GS'DJMAV56BWCVS6VILAYNCVZDOMV3 T4M.2K
DECRYPTED: THE INVASION WILL START ON THE FIRST OF JANUARY 2023.
</pre>
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
using System.Collections.Generic;
using System.Drawing;
 
public class BifidCipher
{
public static void Main(string[] args)
{
string message1 = "ATTACKATDAWN";
string message2 = "FLEEATONCE";
string message3 = "The invasion will start on the first of January".ToUpper().Replace(" ", "");
 
Bifid bifid1 = new Bifid(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ");
Bifid bifid2 = new Bifid(5, "BGWKZQPNDSIOAXEFCLUMTHYVR");
 
RunTest(bifid1, message1);
RunTest(bifid2, message2);
RunTest(bifid2, message1);
RunTest(bifid1, message2);
 
Bifid bifid3 = new Bifid(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
RunTest(bifid3, message3);
}
 
private static void RunTest(Bifid bifid, string message)
{
Console.WriteLine("Using Polybius square:");
bifid.Display();
Console.WriteLine("Message: " + message);
string encrypted = bifid.Encrypt(message);
Console.WriteLine("Encrypted: " + encrypted);
string decrypted = bifid.Decrypt(encrypted);
Console.WriteLine("Decrypted: " + decrypted);
Console.WriteLine();
}
}
 
public class Bifid
{
private char[,] grid;
private Dictionary<char, Point> coordinates = new Dictionary<char, Point>();
 
public Bifid(int n, string text)
{
if (text.Length != n * n)
{
throw new ArgumentException("Incorrect length of text");
}
 
grid = new char[n, n];
int row = 0;
int col = 0;
 
foreach (char ch in text)
{
grid[row, col] = ch;
coordinates[ch] = new Point(row, col);
col += 1;
if (col == n)
{
col = 0;
row += 1;
}
}
 
if (n == 5)
{
coordinates['J'] = coordinates['I'];
}
}
 
public string Encrypt(string text)
{
List<int> rowOne = new List<int>();
List<int> rowTwo = new List<int>();
 
foreach (char ch in text)
{
Point coordinate = coordinates[ch];
rowOne.Add(coordinate.X);
rowTwo.Add(coordinate.Y);
}
 
rowOne.AddRange(rowTwo);
var result = new System.Text.StringBuilder();
 
for (int i = 0; i < rowOne.Count - 1; i += 2)
{
result.Append(grid[rowOne[i], rowOne[i + 1]]);
}
 
return result.ToString();
}
 
public string Decrypt(string text)
{
List<int> row = new List<int>();
 
foreach (char ch in text)
{
Point coordinate = coordinates[ch];
row.Add(coordinate.X);
row.Add(coordinate.Y);
}
 
int middle = row.Count / 2;
List<int> rowOne = row.GetRange(0, middle);
List<int> rowTwo = row.GetRange(middle, row.Count - middle);
var result = new System.Text.StringBuilder();
 
for (int i = 0; i < middle; i++)
{
result.Append(grid[rowOne[i], rowTwo[i]]);
}
 
return result.ToString();
}
 
public void Display()
{
for (int i = 0; i < grid.GetLength(0); i++)
{
for (int j = 0; j < grid.GetLength(1); j++)
{
Console.Write(grid[i, j] + " ");
}
Console.WriteLine();
}
}
}
</syntaxhighlight>
{{out}}
<pre>
Using Polybius square:
A B C D E
F G H I K
L M N O P
Q R S T U
V W X Y Z
Message: ATTACKATDAWN
Encrypted: DQBDAXDQPDQH
Decrypted: ATTACKATDAWN
 
Using Polybius square:
B G W K Z
Q P N D S
I O A X E
F C L U M
T H Y V R
Message: FLEEATONCE
Encrypted: UAEOLWRINS
Decrypted: FLEEATONCE
 
Using Polybius square:
B G W K Z
Q P N D S
I O A X E
F C L U M
T H Y V R
Message: ATTACKATDAWN
Encrypted: EYFENGIWDILA
Decrypted: ATTACKATDAWN
 
Using Polybius square:
A B C D E
F G H I K
L M N O P
Q R S T U
V W X Y Z
Message: FLEEATONCE
Encrypted: HADNAAZDSP
Decrypted: FLEEATONCE
 
Using Polybius square:
A B C D E F
G H I J K L
M N O P Q R
S T U V W X
Y Z 0 1 2 3
4 5 6 7 8 9
Message: THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY
Encrypted: TBPDIPHJSPOTAIVMGPCZKNSCN09BFIHK64I7BM4
Decrypted: THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY
 
 
</pre>
 
Line 449 ⟶ 639:
Encrypted: TBPDIPHJSPOTAIVMGPCZKNSCN09BFIHK64I7BM4
Decrypted: THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY
</pre>
 
=={{header|EasyLang}}==
<syntaxhighlight>
func$ crypt enc msg$ key$ .
n = len msg$
for i to len msg$
c$ = substr msg$ i 1
j = strpos key$ c$ - 1
h[] &= j div 5
h[] &= j mod 5
.
if enc = 1
for i = 1 step 4 to 2 * n - 3
j = h[i] * 5 + h[i + 2] + 1
r$ &= substr key$ j 1
.
for i = 2 step 4 to 2 * n - 2
j = h[i] * 5 + h[i + 2] + 1
r$ &= substr key$ j 1
.
else
for i = 1 to n
j = h[i] * 5 + h[i + n] + 1
r$ &= substr key$ j 1
.
.
return r$
.
func$ conv s$ .
for e$ in strchars s$
h = strcode e$
if h >= 97
h -= 32
.
if h >= 65 and h <= 91
if h = 74
h = 73
.
r$ &= strchar h
.
.
return r$
.
func$ encr msg$ key$ .
return crypt 1 conv msg$ key$
.
func$ decr msg$ key$ .
return crypt 0 msg$ key$
.
key$ = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
h$ = encr "ATTACKATDAWN" key$
print h$
print decr h$ key$
print ""
#
key$ = "BGWKZQPNDSIOAXEFCLUMTHYVR"
h$ = encr "FLEEATONCE" key$
print h$
print decr h$ key$
print ""
h$ = encr "ATTACKATDAWN" key$
print h$
print decr h$ key$
print ""
#
h$ = encr "The invasion will start on the first of January" key$
print h$
print decr h$ key$
</syntaxhighlight>
 
=={{header|EMal}}==
<syntaxhighlight lang="emal">
type PolybiusSquare
model
Map map
List grid
new by int side, text symbols
me.map ← text%Pair[]
me.grid ← List[].with(side, <int y|text[].with(side, <int x|""))
int y, x ← 0
for each text symbol in symbols
me.grid[y][x] ← symbol
me.map[symbol] ← int%int(y => x).named("y", "x")
x++
if x æ side
x ← 0
y++
end
end
end
fun asText = text by block
text result = ""
for int y ← 0; y < me.grid.length; y++
for int x ← 0; x < me.grid[y].length; x++
result.append(" " + me.grid[y][x])
end
result.appendLine()
end
return result
end
end
type BifidCipher
model
PolybiusSquare square
new by PolybiusSquare ←square do end
fun encrypt ← text by text value
List row ← int[].with(value.length * 2)
int y ← 0
int x ← value.length
for each text char in value
Pair p ← me.square.map[char]
row[y++] ← p.y
row[x++] ← p.x
end
text encrypted
for int i ← 0; i < row.length; i += 2
encrypted.append(me.square.grid[row[i]][row[i + 1]])
end
return encrypted
end
fun decrypt ← text by text value
List row ← int[]
for each text char in value
Pair p ← me.square.map[char]
row.append(p.y)
row.append(p.x)
end
int y ← 0
int x ← value.length
text decrypted
for int i ← 0; i < value.length; i++
decrypted.append(me.square.grid[row[y++]][row[x++]])
end
return decrypted
end
end
type Main
List pairs ← Pair[
text%PolybiusSquare("ATTACKATDAWN" => PolybiusSquare(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ")).named("sample", "square"),
text%PolybiusSquare("FLEEATONCE" => PolybiusSquare(5, "BGWKZQPNDSIOAXEFCLUMTHYVR")).named("sample", "square"),
text%PolybiusSquare("ATTACKATDAWN" => PolybiusSquare(5, "BGWKZQPNDSIOAXEFCLUMTHYVR")).named("sample", "square"),
text%PolybiusSquare("The invasion will start on the first of January".upper().replace(" ", "") =>
PolybiusSquare(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")).named("sample", "square")]
for each Pair pair in pairs
writeLine("Using Polybius square:")
write(pair.square)
BifidCipher cipher ← BifidCipher(pair.square)
write("Encrypting '" + pair.sample + "'")
text encrypted ← cipher.encrypt(pair.sample)
write(" => '" + encrypted + "'")
text decrypted ← cipher.decrypt(encrypted)
writeLine(" => '" + decrypted + "'")
writeLine()
end
</syntaxhighlight>
{{ out }}
<pre>
Using Polybius square:
A B C D E
F G H I K
L M N O P
Q R S T U
V W X Y Z
Encrypting 'ATTACKATDAWN' => 'DQBDAXDQPDQH' => 'ATTACKATDAWN'
 
Using Polybius square:
B G W K Z
Q P N D S
I O A X E
F C L U M
T H Y V R
Encrypting 'FLEEATONCE' => 'UAEOLWRINS' => 'FLEEATONCE'
 
Using Polybius square:
B G W K Z
Q P N D S
I O A X E
F C L U M
T H Y V R
Encrypting 'ATTACKATDAWN' => 'EYFENGIWDILA' => 'ATTACKATDAWN'
 
Using Polybius square:
A B C D E F
G H I J K L
M N O P Q R
S T U V W X
Y Z 0 1 2 3
4 5 6 7 8 9
Encrypting 'THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY' => 'TBPDIPHJSPOTAIVMGPCZKNSCN09BFIHK64I7BM4' => 'THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY'
</pre>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
clear local fn recode( t as CFStringRef, code as CFStringRef ) as CFStringRef
CFStringRef s = @""
Short i, k, w = sqr( len( code ) )
for i = 0 to len( t ) - 1 step 2
k = intval( mid( t, i, 2 ) ) // Get ‘coordinates’ of char in code string
k = w * ( k / 10 ) + k mod 10
s = fn StringByAppendingString( s, mid( code, k, 1 ) )
next
end fn = s
 
//
 
clear local fn encode( s as CFStringRef, code as CFStringRef ) as CFStringRef
CFStringRef a = @"", b = @"", c
Short i, k, w = sqr( len( code ) )
if w == 5 then s = fn StringByReplacingOccurrencesOfString( s, @"J", @"I" )
print s
for i = 0 to len( s ) - 1
c = mid( s, i, 1 )
k = instr( 0, code, c ) // Put row in one string, column in the other
a = fn StringByAppendingString( a, fn StringWithFormat( @"%d", k / w ) )
b = fn StringByAppendingString( b, fn StringWithFormat( @"%d", k mod w ) )
next
a = fn StringByAppendingString( a, b ) // Combine the two strings, and recode
end fn = fn recode( a, code )
 
//
 
clear local fn decode( s as CFStringRef, code as CFStringRef ) as CFStringRef
CFStringRef a = @"", b = @"", c
Short i, k, w = sqr( len( code ) )
for i = 0 to ( len( s ) - 1 )
c = mid( s, i, 1 )
k = instr( 0, code, c ) // Put row and columm in one long string
a = fn StringByAppendingString( a, fn StringWithFormat( @"%d%d", k / w, k mod w ) )
next
for i = 0 to len( a ) / 2 - 1 // Take row from first half of string, column from second
c = fn StringByAppendingString( mid( a, i, 1 ), mid( a, i + len( a ) / 2 , 1 ) )
b = fn StringByAppendingString( b , c ) // Combine, and recode
next
end fn = fn recode( b, code )
 
//
 
print fn encode( @"ATTACKATDAWN", @"ABCDEFGHIKLMNOPQRSTUVWXYZ" )
print fn decode( @"DQBDAXDQPDQH", @"ABCDEFGHIKLMNOPQRSTUVWXYZ" )
print
print fn encode( @"FLEEATONCE", @"BGWKZQPDNSIOAXEFCLUMTHYVR" )
print fn decode( @"UAEOLWRINS", @"BGWKZQPDNSIOAXEFCLUMTHYVR" )
print
print fn encode( @"HAPPY40THDAD", @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" )
print fn decode( @"GO31GAGVANJD", @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" )
 
handleevents
</syntaxhighlight>
{{ out }}
<pre>
ATTACKATDAWN
DQBDAXDQPDQH
ATTACKATDAWN
 
FLEEATONCE
UAEOLWRINS
FLEEATONCE
 
HAPPY40THDAD
GO31GAGVANJD
HAPPY40THDAD
</pre>
 
Line 1,460 ⟶ 1,920:
Decrypted: THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY
</pre>
 
=={{header|Quackery}}==
 
<code>transpose</code> is defined at [[Matrix transposition#Quackery]].
 
<syntaxhighlight lang="Quackery"> [ $ "" swap
witheach
[ upper
dup char I > if [ 1 - ]
dup char A char Z
within iff
[ char A - join ]
else drop ] ] is ->0..24 ( $ --> [ )
 
[ $ "" swap
witheach
[ char A +
dup char I > if 1+
join ] ] is ->A..Z ( [ --> $ )
 
[ [] 5 times
[ dip ->0..24 join ] ] is makesquare ( $ $ $ $ $ --> [ )
 
[ dup witheach
[ i^ unrot poke ] ] is makeindex ( [ --> [ )
 
[ dup temp put
makeindex temp put
->0..24
[] swap witheach
[ temp share swap peek
5 /mod join
nested join ]
temp release
transpose
unpack join
[] swap
dup size 2 / times
[ 2 split dip
[ nested join ] ]
drop
$ "" swap
witheach
[ unpack swap 5 * +
temp share swap peek
join ]
->A..Z
temp release ] is encrypt ( $ [ --> $ )
 
[ dup temp put
makeindex temp put
->0..24
[] swap witheach
[ temp share swap peek
5 /mod join join ]
temp release
dup size 2 / split
2 pack
transpose
[] swap witheach
[ unpack swap 5 * +
temp share swap peek
join ]
->A..Z
temp release ] is decrypt ( $ [ --> $ )
 
[ $ "ABCDE"
$ "FGHIK"
$ "LMNOP"
$ "QRSTU"
$ "VWXYZ"
makesquare ] constant is tasksquare ( --> [ )
 
[ $ "BGWKZ"
$ "QPNDS"
$ "IOAXE"
$ "FCLUM"
$ "THYVR"
makesquare ] constant is wikisquare ( --> [ )
 
[ $ "QUACK"
$ "DEPTH"
$ "LYING"
$ "FORMS"
$ "BVWXZ"
makesquare ] constant is ducksquare ( --> [ )
 
 
say "Using tasksquare:" cr
$ "Attack at dawn." dup echo$ say " -> "
tasksquare encrypt dup echo$ say " -> "
tasksquare decrypt echo$
cr cr
say "Using wikisquare:" cr
$ "Flee at once." dup echo$ say " -> "
wikisquare encrypt dup echo$ say " -> "
wikisquare decrypt echo$
cr cr
say "Using ducksquare:" cr
$ "The invasion will start on the first of January." dup echo$ cr say " -> "
ducksquare encrypt dup echo$ cr say " -> "
ducksquare decrypt echo$
</syntaxhighlight>
 
{{out}}
 
<pre>Using tasksquare:
Attack at dawn. -> DQBDAXDQPDQH -> ATTACKATDAWN
 
Using wikisquare:
Flee at once. -> UAEOLWRINS -> FLEEATONCE
 
Using ducksquare:
The invasion will start on the first of January.
-> EPGCNGINDORETNOMLLCNVNPWTIQXIOMVAGOANPY
-> THEINVASIONWILLSTARTONTHEFIRSTOFIANUARY
</pre>
 
=={{header|Raku}}==
Technically incorrect as the third part doesn't "Convert ... to upper case and ignore spaces".
Line 1,523 ⟶ 2,101:
Encrypted : NGiw3okfXj4XoVE_NjWcLK4Sy28EivKo3aeNiti3N3z6HCHno6Fkf
Decrypted : The_invasion_will_start_on_the_first_of_January_2023.</pre>
=={{header|RPL}}==
« DUP SIZE √ "" → in key n out
« { } DUP
1 in SIZE '''FOR''' j
key in j DUP SUB
POS 1 - n MOD LASTARG / IP
SWAP ROT SWAP + ROT ROT + SWAP
'''NEXT'''
+ 'in' STO
1 in SIZE '''FOR''' j
'out' key
in j DUP 1 + SUB
OBJ→ DROP SWAP n * + 1 +
DUP SUB STO+
2 '''STEP'''
out
» » '<span style="color:blue">→BIFCOD</span>' STO
« DUP SIZE √ "" → in key n out
« { }
1 in SIZE '''FOR''' j
key in j DUP SUB POS
1 - n MOD LASTARG / IP
ROT SWAP + SWAP +
'''NEXT'''
DUP 'in' STO SIZE 2 /
1 OVER '''FOR''' j
'out' key
in j GET n * in 5 PICK j + GET + 1 +
DUP SUB STO+
'''NEXT'''
DROP out
» » '<span style="color:blue">→BIFDEC</span>' STO
« { "ATTACKATDAWN" "ABCDEFGHIKLMNOPQRSTUVWXYZ"
"FLEEATONCE" "BGWKZQPNDSIOAXEFCLUMTHYVR"
"ATTACKATDAWN" "BGWKZQPNDSIOAXEFCLUMTHYVR"
"THE INVASION WILL START ON THE FIRST OF JANUARY" "ABCDEFGHIJKLMNOPQRSTUVWXYZ 123456789" }
→ examples
« 1 examples SIZE '''FOR''' j
examples j GETI ROT ROT GET
<span style="color:blue">→BIFCOD</span> DUP examples j 1 + GET
<span style="color:blue">→BIFDEC</span> 2 →LIST
2 '''STEP'''
» » '<span style="color:blue">TASK</span>' STO
 
{{out}}
<pre>
4: { "DQBDAXDQPDQH" "ATTACKATDAWN" }
3: { "UAEOLWRINS" "FLEEATONCE" }
2: { "EYFENGIWDILA" "ATTACKATDAWN" }
1: { "TEISTO1HKVCWO1GYIV EGPCZKOJAOI 9MG5OIH 64IRPBM4" "THE INVASION WILL START ON THE FIRST OF JANUARY" }
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby" line>
Line 1,528 ⟶ 2,160:
msg.upcase!
msg.delete!(' ')
msg.delete!('J') if square.index(' J') == nil
end
 
Line 1,668 ⟶ 2,300:
 
However, the following just uses the standard version of the cipher.
<syntaxhighlight lang="ecmascriptwren">import "./str" for Str
import "./seq" for Lst
 
226

edits