Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Bifid-cipher/00-META.yaml
Normal file
4
Task/Bifid-cipher/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Encryption
|
||||
from: http://rosettacode.org/wiki/Bifid_cipher
|
||||
61
Task/Bifid-cipher/00-TASK.txt
Normal file
61
Task/Bifid-cipher/00-TASK.txt
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
;Description
|
||||
The [[wp:Bifid_cipher|'''Bifid cipher''']] is a polygraphic substitution cipher which was invented by [[wp:Félix_ Delastelle|Félix Delastelle]] in around 1901. It uses a 5 x 5 [[wp:Polybius_square|Polybius square]] combined with transposition and fractionation to encrypt a message. Any 5 x 5 Polybius square can be used but, as it only has 25 cells and there are 26 letters of the (English) alphabet, one cell needs to represent two letters - I and J being a common choice.
|
||||
|
||||
;Operation
|
||||
Suppose we want to encrypt the message "ATTACKATDAWN".
|
||||
|
||||
We use this archetypal Polybius square where I and J share the same position.
|
||||
<pre>
|
||||
x/y 1 2 3 4 5
|
||||
-------------
|
||||
1 | A B C D E
|
||||
2 | F G H I K
|
||||
3 | L M N O P
|
||||
4 | Q R S T U
|
||||
5 | V W X Y Z
|
||||
</pre>
|
||||
The message is first converted to its x, y coordinates, but they are written vertically beneath.
|
||||
|
||||
<pre>
|
||||
A T T A C K A T D A W N
|
||||
1 4 4 1 1 2 1 4 1 1 5 3
|
||||
1 4 4 1 3 5 1 4 4 1 2 3
|
||||
</pre>
|
||||
|
||||
They are then arranged in a row.
|
||||
|
||||
<pre>
|
||||
1 4 4 1 1 2 1 4 1 1 5 3 1 4 4 1 3 5 1 4 4 1 2 3
|
||||
</pre>
|
||||
|
||||
Finally, they are divided up into pairs which are used to look up the encrypted letters in the square.
|
||||
|
||||
<pre>
|
||||
14 41 12 14 11 53 14 41 35 14 41 23
|
||||
D Q B D A X D Q P D Q H
|
||||
</pre>
|
||||
|
||||
The encrypted message is therefore "DQBDAXDQPDQH".
|
||||
|
||||
Decryption can be achieved by simply reversing these steps.
|
||||
|
||||
;Task
|
||||
Write routines in your language to encrypt and descrypt a message using the Bifid cipher.
|
||||
|
||||
Use them to verify (including subsequent decryption):
|
||||
|
||||
1. The above example.
|
||||
|
||||
2. The example in the Wikipedia article using the message and Polybius square therein.
|
||||
|
||||
3. The above example but using the Polybius square in the Wikipedia article to illustrate that it doesn't matter which square you use as long, of course, as the same one is used for both encryption and decryption.
|
||||
|
||||
In addition, encrypt and decrypt the message "The invasion will start on the first of January" using any Polybius square you like. Convert the message to upper case and ignore spaces.
|
||||
|
||||
;Bonus
|
||||
Suggest a way in which the cipher could be modified so that ALL 26 letters can be uniquely encrypted.
|
||||
|
||||
;Related task
|
||||
[[Playfair_cipher|Playfair cipher]]
|
||||
<br><br>
|
||||
|
||||
30
Task/Bifid-cipher/Ada/bifid-cipher.ada
Normal file
30
Task/Bifid-cipher/Ada/bifid-cipher.ada
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
-- Bifid cipher
|
||||
-- J. Carter 2023 May
|
||||
-- The Bifid cipher is included as part of the PragmAda Reusable Components (https://github.com/jrcarter/PragmARC)
|
||||
|
||||
with Ada.Text_IO;
|
||||
with PragmARC.Encryption.Bifid;
|
||||
|
||||
procedure Bifid_Test is
|
||||
package Bifid renames PragmARC.Encryption.Bifid;
|
||||
|
||||
Key_1 : constant Bifid.Square_Layout := ("ABCDE", "FGHIK", "LMNOP", "QRSTU", "VWXYZ");
|
||||
Key_2 : constant Bifid.Square_Layout := ("BGWKZ", "QPNDS", "IOAXE", "FCLUM", "THYVR");
|
||||
|
||||
Msg_1 : constant String := "ATTACKATDAWN";
|
||||
Msg_2 : constant String := "FLEEATONCE";
|
||||
Msg_3 : constant String := "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY";
|
||||
|
||||
Crypt_1 : String (Msg_1'Range);
|
||||
Crypt_2 : String (Msg_2'Range);
|
||||
Crypt_3 : String (Msg_3'Range);
|
||||
begin -- Bifid_Test
|
||||
Crypt_1 := Bifid.Encrypt (Msg_1, Key_1);
|
||||
Ada.Text_IO.Put_Line (Item => Msg_1 & " => " & Crypt_1 & " => " & Bifid.Decrypt (Crypt_1, Key_1) );
|
||||
Crypt_2 := Bifid.Encrypt (Msg_2, Key_2);
|
||||
Ada.Text_IO.Put_Line (Item => Msg_2 & " => " & Crypt_2 & " => " & Bifid.Decrypt (Crypt_2, Key_2) );
|
||||
Crypt_1 := Bifid.Encrypt (Msg_1, Key_2);
|
||||
Ada.Text_IO.Put_Line (Item => Msg_1 & " => " & Crypt_1 & " => " & Bifid.Decrypt (Crypt_1, Key_2) );
|
||||
Crypt_3 := Bifid.Encrypt (Msg_3, Key_2);
|
||||
Ada.Text_IO.Put_Line (Item => Msg_3 & " => " & Crypt_3 & " => " & Bifid.Decrypt (Crypt_3, Key_2) );
|
||||
end Bifid_Test;
|
||||
91
Task/Bifid-cipher/AppleScript/bifid-cipher-1.applescript
Normal file
91
Task/Bifid-cipher/AppleScript/bifid-cipher-1.applescript
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
(* The "square" here is only notional, the characters' coordinates being calculated
|
||||
from their offsets in a linear text key. But a square key is accepted if the
|
||||
signaller's careless enough to keep or transmit one in this form. *)
|
||||
on bifidEncipher(message, square)
|
||||
return transcipher(message, square, 1)
|
||||
end bifidEncipher
|
||||
|
||||
on bifidDecipher(message, square)
|
||||
return transcipher(message, square, 2)
|
||||
end bifidDecipher
|
||||
|
||||
on transcipher(message, square, code) -- code: 1 = encipher, 2 = decipher.
|
||||
-- Check and massage the input.
|
||||
set message to join(message's words, "")
|
||||
if (message contains ".") then set message to replaceText(".", "", message)
|
||||
set square to join(join(square, "")'s words, "")
|
||||
set squarea to (count square)
|
||||
set sqrt to (squarea ^ 0.5) as integer
|
||||
if (sqrt * sqrt ≠ squarea) then error "Invalid key."
|
||||
ignoring case
|
||||
if ((sqrt < 6) and (message contains "J")) then ¬
|
||||
set message to replaceText("J", "I", message)
|
||||
end ignoring
|
||||
-- Calculate coordinates from the message characters' offsets in the "square" text
|
||||
-- and either split and recombine them (when enciphering) or not (deciphering).
|
||||
set list1 to {}
|
||||
set list2 to {{}, list1}'s item code
|
||||
set astid to AppleScript's text item delimiters
|
||||
ignoring case and diacriticals
|
||||
repeat with chr in message
|
||||
set AppleScript's text item delimiters to chr
|
||||
set |offset - 1| to (count square's first text item)
|
||||
set list1's end to |offset - 1| div sqrt + 1
|
||||
set list2's end to |offset - 1| mod sqrt + 1
|
||||
end repeat
|
||||
end ignoring
|
||||
set AppleScript's text item delimiters to astid
|
||||
set coords to {list1 & list2, list1}'s item code
|
||||
-- Calculate new offsets from the appropriate numbers in the coords list
|
||||
-- and get the characters offset by those amounts in the "square" text.
|
||||
set chrs to {}
|
||||
set nCoords to (count coords)
|
||||
set indexDifference to {1, nCoords div 2}'s item code
|
||||
repeat with i from 1 to (nCoords div code) by (3 - code)
|
||||
set |offset| to ((coords's item i) - 1) * sqrt + (coords's item (i + indexDifference))
|
||||
set chrs's end to square's character |offset|
|
||||
end repeat
|
||||
return join(chrs, "")
|
||||
end transcipher
|
||||
|
||||
on join(lst, delim)
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to delim
|
||||
set txt to lst as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return txt
|
||||
end join
|
||||
|
||||
on replaceText(searchText, replacement, mainText)
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to searchText
|
||||
set textItems to mainText's text items
|
||||
set AppleScript's text item delimiters to replacement
|
||||
set mainText to textItems as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return mainText
|
||||
end replaceText
|
||||
|
||||
on task()
|
||||
set output to {}
|
||||
repeat with this in {{"Given example:", "ATTACKATDAWN", "ABCDEFGHIKLMNOPQRSTUVWXYZ"}, ¬
|
||||
{"Wikipedia example:", "FLEEATONCE", {"BGWKZ", "QPNDS", "IOAXE", "FCLUM", "THYVR"}}, ¬
|
||||
{"A 6 x 6 square allows all 36 letters & digits to be encoded:", ¬
|
||||
"The invasion will start on the 1st of January", ¬
|
||||
"THEQUI
|
||||
9CKBR0
|
||||
1OWNF8
|
||||
7XJMP2
|
||||
3SVLA6
|
||||
5ZYDG4"}}
|
||||
set {heading, message, square} to this
|
||||
set encrypted to bifidEncipher(message, square)
|
||||
set decrypted to bifidDecipher(encrypted, square)
|
||||
set output's end to heading
|
||||
set output's end to message & " --> " & encrypted & " --> " & decrypted
|
||||
end repeat
|
||||
|
||||
return join(output, linefeed)
|
||||
end task
|
||||
|
||||
task()
|
||||
6
Task/Bifid-cipher/AppleScript/bifid-cipher-2.applescript
Normal file
6
Task/Bifid-cipher/AppleScript/bifid-cipher-2.applescript
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"Given example:
|
||||
ATTACKATDAWN --> DQBDAXDQPDQH --> ATTACKATDAWN
|
||||
Wikipedia example:
|
||||
FLEEATONCE --> UAEOLWRINS --> FLEEATONCE
|
||||
A 6 x 6 square allows all 36 letters & digits to be encoded:
|
||||
The invasion will start on the 1st of January --> TTFAEWUAU9WTE3WP1S5KDF0B8M9AH7KHHVLAV --> THEINVASIONWILLSTARTONTHE1STOFJANUARY"
|
||||
111
Task/Bifid-cipher/C++/bifid-cipher.cpp
Normal file
111
Task/Bifid-cipher/C++/bifid-cipher.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
typedef std::pair<int32_t, int32_t> point;
|
||||
|
||||
class Bifid {
|
||||
public:
|
||||
Bifid(const int32_t& n, const std::string& text) {
|
||||
if ( text.length() != n * n ) {
|
||||
throw new std::invalid_argument("Incorrect length of text");
|
||||
}
|
||||
|
||||
grid.resize(n);
|
||||
for ( uint64_t i = 0; i < grid.size(); i++ ) {
|
||||
grid[i].resize(n);
|
||||
}
|
||||
|
||||
int32_t row = 0;
|
||||
int32_t col = 0;
|
||||
for ( char ch : text ) {
|
||||
grid[row][col] = ch;
|
||||
coordinates[ch] = point(row, col);
|
||||
col += 1;
|
||||
if ( col == n ) {
|
||||
col = 0;
|
||||
row += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( n == 5 ) {
|
||||
coordinates['J'] = coordinates['I'];
|
||||
}
|
||||
}
|
||||
|
||||
std::string encrypt(const std::string& text) {
|
||||
std::vector<int32_t> row_one, row_two;
|
||||
for ( char ch : text ) {
|
||||
point coordinate = coordinates[ch];
|
||||
row_one.push_back(coordinate.first);
|
||||
row_two.push_back(coordinate.second);
|
||||
}
|
||||
|
||||
row_one.insert(row_one.end(), row_two.begin(), row_two.end());
|
||||
std::string result;
|
||||
for ( uint64_t i = 0; i < row_one.size() - 1; i += 2 ) {
|
||||
result += grid[row_one[i]][row_one[i + 1]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string decrypt(const std::string& text) {
|
||||
std::vector<int32_t> row;
|
||||
for ( char ch : text ) {
|
||||
point coordinate = coordinates[ch];
|
||||
row.push_back(coordinate.first);
|
||||
row.push_back(coordinate.second);
|
||||
}
|
||||
|
||||
const int middle = row.size() / 2;
|
||||
std::vector<int32_t> row_one = { row.begin(), row.begin() + middle };
|
||||
std::vector<int32_t> row_two = { row.begin() + middle, row.end() };
|
||||
std::string result;
|
||||
for ( int32_t i = 0; i < middle; i++ ) {
|
||||
result += grid[row_one[i]][row_two[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void display() const {
|
||||
for ( std::vector<char> row : grid ) {
|
||||
for ( char ch : row ) {
|
||||
std::cout << ch << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::vector<std::vector<char>> grid;
|
||||
std::unordered_map<char, point> coordinates;
|
||||
};
|
||||
|
||||
void runTest(Bifid bifid, std::string message) {
|
||||
std::cout << "Using Polybius square:" << std::endl;
|
||||
bifid.display();
|
||||
std::cout << "Message: " << message << std::endl;
|
||||
std::string encrypted = bifid.encrypt(message);
|
||||
std::cout << "Encrypted: " << encrypted << std::endl;
|
||||
std::string decrypted = bifid.decrypt(encrypted);
|
||||
std::cout << "Decrypted: " << decrypted << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
const std::string message1 = "ATTACKATDAWN";
|
||||
const std::string message2 = "FLEEATONCE";
|
||||
const std::string message3 = "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY";
|
||||
|
||||
Bifid bifid1(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ");
|
||||
Bifid bifid2(5, "BGWKZQPNDSIOAXEFCLUMTHYVR");
|
||||
|
||||
runTest(bifid1, message1);
|
||||
runTest(bifid2, message2);
|
||||
runTest(bifid2, message1);
|
||||
runTest(bifid1, message2);
|
||||
|
||||
Bifid bifid3(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
runTest(bifid3, message3);
|
||||
}
|
||||
4
Task/Bifid-cipher/J/bifid-cipher-1.j
Normal file
4
Task/Bifid-cipher/J/bifid-cipher-1.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
alpha=: a.{~65+i.26
|
||||
normalize=: {{ rplc&'JI'(toupper y)([-.-.)alpha }}
|
||||
bifid=: {{ m{~_2 (t&#.)\,|:(t,t=.%:#m)#:m i.y([-.-.)m }}
|
||||
difib=: {{ m{~t#.|:(|.@$$,)(t,t=.%:#m)#:m i.y([-.-.)m }}
|
||||
24
Task/Bifid-cipher/J/bifid-cipher-2.j
Normal file
24
Task/Bifid-cipher/J/bifid-cipher-2.j
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
ref1=: ~.normalize alpha
|
||||
ref2=: 'BGWKZQPNDSIOAXEFCLUMTHYVR'
|
||||
ref3=: 'PLAYFIREXMBCDGHKNOQSTUVWZ'
|
||||
|
||||
ref1 bifid normalize 'attack at dawn'
|
||||
DQBDAXDQPDQH
|
||||
ref1 difib ref1 bifid normalize 'attack at dawn'
|
||||
ATTACKATDAWN
|
||||
ref2 bifid normalize 'flee at once'
|
||||
UAEOLWRINS
|
||||
ref2 difib ref2 bifid normalize 'flee at once'
|
||||
FLEEATONCE
|
||||
ref2 bifid normalize 'attack at dawn'
|
||||
EYFENGIWDILA
|
||||
ref2 difib ref2 bifid normalize 'attack at dawn'
|
||||
ATTACKATDAWN
|
||||
ref3 bifid normalize 'The invasion will start on the first of January'
|
||||
VRSYXSIYTMQVIRSKISLPVLDTCKRTCAIVTMATCEX
|
||||
ref3 difib ref3 bifid normalize 'The invasion will start on the first of January'
|
||||
THEINVASIONWILLSTARTONTHEFIRSTOFIANUARY
|
||||
(_81{.123{.a.)bifid 'The invasion will start on the first of January'
|
||||
TgqhpqpqxzpxfqzoKqhxw/O3eWH53BYw`+Be8F1
|
||||
(_81{.123{.a.)difib(_81{.123{.a.)bifid 'The invasion will start on the first of January'
|
||||
TheinvasionwillstartonthefirstofJanuary
|
||||
107
Task/Bifid-cipher/Java/bifid-cipher.java
Normal file
107
Task/Bifid-cipher/Java/bifid-cipher.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class BifidCipher {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
final String message1 = "ATTACKATDAWN";
|
||||
final String message2 = "FLEEATONCE";
|
||||
final String message3 = "The invasion will start on the first of January".toUpperCase().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 aBifid, String aMessage) {
|
||||
System.out.println("Using Polybius square:");
|
||||
aBifid.display();
|
||||
System.out.println("Message: " + aMessage);
|
||||
String encrypted = aBifid.encrypt(aMessage);
|
||||
System.out.println("Encrypted: " + encrypted);
|
||||
String decrypted = aBifid.decrypt(encrypted);
|
||||
System.out.println("Decrypted: " + decrypted);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final class Bifid {
|
||||
|
||||
public Bifid(int aN, String aText) {
|
||||
if ( aText.length() != aN * aN ) {
|
||||
throw new IllegalArgumentException("Incorrect length of text");
|
||||
}
|
||||
|
||||
grid = new char[aN][aN];
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
for ( char ch : aText.toCharArray() ) {
|
||||
grid[row][col] = ch;
|
||||
coordinates.put(ch, new Point(row, col) );
|
||||
col += 1;
|
||||
if ( col == aN ) {
|
||||
col = 0;
|
||||
row += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( aN == 5 ) {
|
||||
coordinates.put('J', coordinates.get('I'));
|
||||
}
|
||||
}
|
||||
|
||||
public String encrypt(String aText) {
|
||||
List<Integer> rowOne = new ArrayList<Integer>();
|
||||
List<Integer> rowTwo = new ArrayList<Integer>();
|
||||
for ( char ch : aText.toCharArray() ) {
|
||||
Point coordinate = coordinates.get(ch);
|
||||
rowOne.add(coordinate.x);
|
||||
rowTwo.add(coordinate.y);
|
||||
}
|
||||
|
||||
rowOne.addAll(rowTwo);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for ( int i = 0; i < rowOne.size() - 1; i += 2 ) {
|
||||
result.append(grid[rowOne.get(i)][rowOne.get(i + 1)]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String decrypt(String aText) {
|
||||
List<Integer> row = new ArrayList<Integer>();
|
||||
for ( char ch : aText.toCharArray() ) {
|
||||
Point coordinate = coordinates.get(ch);
|
||||
row.add(coordinate.x);
|
||||
row.add(coordinate.y);
|
||||
}
|
||||
|
||||
final int middle = row.size() / 2;
|
||||
List<Integer> rowOne = row.subList(0, middle);
|
||||
List<Integer> rowTwo = row.subList(middle, row.size());
|
||||
StringBuilder result = new StringBuilder();
|
||||
for ( int i = 0; i < middle; i++ ) {
|
||||
result.append(grid[rowOne.get(i)][rowTwo.get(i)]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public void display() {
|
||||
Arrays.stream(grid).forEach( row -> System.out.println(Arrays.toString(row)) );
|
||||
}
|
||||
|
||||
private char[][] grid;
|
||||
private Map<Character, Point> coordinates = new HashMap<Character, Point>();
|
||||
|
||||
}
|
||||
25
Task/Bifid-cipher/Julia/bifid-cipher.julia
Normal file
25
Task/Bifid-cipher/Julia/bifid-cipher.julia
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
polybius(text) = Char.(reshape(Int.(collect(text)), isqrt(length(text)), :)')
|
||||
|
||||
function encrypt(message, poly)
|
||||
positions = [findall(==(c), poly)[1] for c in message]
|
||||
numbers = vcat([c[1] for c in positions], [c[2] for c in positions])
|
||||
return String([poly[numbers[i], numbers[i+1]] for i in 1:2:length(numbers)-1])
|
||||
end
|
||||
|
||||
function decrypt(message, poly)
|
||||
n = length(message)
|
||||
positions = [findall(==(c), poly)[1] for c in message]
|
||||
numbers = reduce(vcat, [[c[1], c[2]] for c in positions])
|
||||
return String([poly[numbers[i], numbers[i+n]] for i in 1:n])
|
||||
end
|
||||
|
||||
|
||||
for (key, text) in [("ABCDEFGHIKLMNOPQRSTUVWXYZ", "ATTACKATDAWN"), ("BGWKZQPNDSIOAXEFCLUMTHYVR", "FLEEATONCE"),
|
||||
([' '; '.'; 'A':'Z'; 'a':'z'; '0':'9'], "The invasion will start on the first of January 2023.")]
|
||||
poly = polybius(key)
|
||||
encrypted = encrypt(text, poly)
|
||||
decrypted = decrypt(encrypted, poly)
|
||||
println("Using polybius:")
|
||||
display(poly)
|
||||
println("\n Message: $text\n Encrypted: $encrypted\n Decrypted: $decrypted\n\n")
|
||||
end
|
||||
77
Task/Bifid-cipher/Nim/bifid-cipher.nim
Normal file
77
Task/Bifid-cipher/Nim/bifid-cipher.nim
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import std/[sequtils, strutils, tables]
|
||||
|
||||
# Description of a Bifid cipher.
|
||||
type Bifid[N: static Positive] = object
|
||||
grid: array[1..N, array[1..N, char]]
|
||||
coords: Table[char, (int, int)]
|
||||
|
||||
proc initBifid(N: static Positive; text: string): Bifid[N] =
|
||||
# Initialize a Bifid cipher.
|
||||
assert text.len == N * N
|
||||
var row, col = 1
|
||||
for c in text:
|
||||
result.grid[row][col] = c
|
||||
result.coords[c] = (row, col)
|
||||
inc col
|
||||
if col > N:
|
||||
col = 1
|
||||
inc row
|
||||
if N == 5:
|
||||
result.coords['J'] = result.coords['I']
|
||||
|
||||
func encrypt(bifid: Bifid; text: string): string =
|
||||
## Encrypt "text" using the given cipher.
|
||||
var row1, row2: seq[int]
|
||||
for ch in text:
|
||||
let coords = bifid.coords[ch]
|
||||
row1.add coords[0]
|
||||
row2.add coords[1]
|
||||
let row = row1 & row2
|
||||
for i in countup(0, row.high, 2):
|
||||
result.add bifid.grid[row[i]][row[i+1]]
|
||||
|
||||
func decrypt(bifid: Bifid; text: string): string =
|
||||
## Decrypt "text" using the given cipher.
|
||||
var row: seq[int]
|
||||
for ch in text:
|
||||
let coords = bifid.coords[ch]
|
||||
row.add [coords[0], coords[1]]
|
||||
let m = row.len shr 1
|
||||
let row1 = row[0..<m]
|
||||
let row2 = row[m..^1]
|
||||
for i in 0..<m:
|
||||
result.add bifid.grid[row1[i]][row2[i]]
|
||||
|
||||
func `$`(bifid: Bifid): string =
|
||||
## Display the Polybius square of a Bifid cipher.
|
||||
result = " " & toSeq(1..bifid.N).join(" ") & '\n'
|
||||
for row in 1..bifid.N:
|
||||
result.add alignLeft($row, 2) & bifid.grid[row].join(" ") & '\n'
|
||||
|
||||
proc runTest(bifid: Bifid; message: string) =
|
||||
## Run the test with given cipher and message.
|
||||
echo "Using Polybius square:"
|
||||
echo bifid
|
||||
echo "Message: ", message
|
||||
let encrypted = bifid.encrypt(message)
|
||||
echo "Encrypted: ", encrypted
|
||||
let decrypted = bifid.decrypt(encrypted)
|
||||
echo "Decrypted: ", decrypted
|
||||
echo("\n─────────────────────────")
|
||||
|
||||
const
|
||||
Message1 = "ATTACKATDAWN"
|
||||
Message2 = "FLEEATONCE"
|
||||
Message3 = "The invasion will start on the first of January".toUpperAscii.replace(" ")
|
||||
|
||||
# Using 5x5 Polybius squares.
|
||||
const
|
||||
Bifid1 = initBifid(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ")
|
||||
Bifid2 = initBifid(5, "BGWKZQPNDSIOAXEFCLUMTHYVR")
|
||||
for (bifid, message) in [(Bifid1, Message1), (Bifid2, Message2),
|
||||
(Bifid2, Message1), (Bifid1, Message3)]:
|
||||
runTest(bifid, message)
|
||||
|
||||
# Using a 6x6 Polybius square with 26 letters and 10 digits.
|
||||
const Bifid3 = initBifid(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
runTest(Bifid3, Message3)
|
||||
47
Task/Bifid-cipher/Perl/bifid-cipher.pl
Normal file
47
Task/Bifid-cipher/Perl/bifid-cipher.pl
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
use v5.36;
|
||||
use builtin <indexed floor>;
|
||||
use experimental qw(builtin for_list);
|
||||
use List::Util 'max';
|
||||
|
||||
sub table ($c, @V) { my $t = $c * (my $w = 2 + length max map { length } @V); ( sprintf( ('%'.$w.'s')x@V, @V) ) =~ s/.{1,$t}\K/\n/gr }
|
||||
|
||||
sub polybius ($text) {
|
||||
my %p;
|
||||
my $n = floor sqrt length $text;
|
||||
for my($k,$v) (indexed split '', $text) {
|
||||
$p{$v} = join ' ', $k%$n, int $k/$n
|
||||
}
|
||||
%p;
|
||||
}
|
||||
|
||||
sub encrypt ($text, %P) {
|
||||
my(%I, @c, $encrypted);
|
||||
for my($k,$v) (%P) { $I{$v} = $k }
|
||||
for my ($n,$char) (indexed split '', ($text =~ s/\s//gr)) {
|
||||
for my($m,$i) (indexed split ' ', $P{$char}) { $c[$m][$n] = $i }
|
||||
}
|
||||
for my($i,$j) ($c[1]->@*, $c[0]->@*) { $encrypted .= $I{"$j $i"} }
|
||||
$encrypted
|
||||
}
|
||||
|
||||
sub decrypt ($text, %P) {
|
||||
my($decrypted, $l, %I, @c) = ('', length($text));
|
||||
for my($k,$v) (%P) { $I{$v} = $k }
|
||||
for (split '', $text) {
|
||||
for my($i,$j) (split ' ', $P{$_}) { unshift @c, $i, $j }
|
||||
}
|
||||
substr $decrypted, 0, 0, $I{ "$c[$_] $c[$_+$l]" } for 0 .. $l-1;
|
||||
$decrypted;
|
||||
}
|
||||
|
||||
for my($polybius,$message) (
|
||||
join('','A'..'Z') =~ s/J//r, 'ATTACK AT DAWN',
|
||||
'BGWKZQPNDSIOAXEFCLUMTHYVR', 'FLEE AT ONCE',
|
||||
join('','_.', 'A'..'Z', 'a'..'z', '0'..'9'), 'The_invasion_will_start_on_the_first_of_January_2023.',
|
||||
) {
|
||||
my %Ptable = polybius $polybius;
|
||||
say "\nUsing polybius:\n" . table sqrt length $polybius, split '', $polybius;
|
||||
say 'Message : ' . $message;
|
||||
say 'Encrypted : ' . (my $encrypted = encrypt $message, %Ptable);
|
||||
say 'Decrypted : ' . decrypt $encrypted, %Ptable;
|
||||
}
|
||||
41
Task/Bifid-cipher/Phix/bifid-cipher.phix
Normal file
41
Task/Bifid-cipher/Phix/bifid-cipher.phix
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">encrypt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">decrypt</span>
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">bifid</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">polybius</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ed</span><span style="color: #0000FF;">)</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: #004080;">sequence</span> <span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">dy</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000000;">dxy</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;">msg</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">polybius</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">/</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">dy</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">ed</span><span style="color: #0000FF;">=</span><span style="color: #000000;">encrypt</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">dxy</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">&</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000080;font-style:italic;">-- "simply reversing these steps" - yeah, right...</span>
|
||||
<span style="color: #000000;">dxy</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split_by</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">flatten</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">})),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">)))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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;">dxy</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dxy</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">][</span><span style="color: #000000;">y</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;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">polybius</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">polybius</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">then</span> <span style="color: #000000;">msg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"J"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"I"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">polybius</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">enc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bifid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">polybius</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">encrypt</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">dec</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bifid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">polybius</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">decrypt</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;">"For %dx%d polybius %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n "</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;">"Message : %s\nEncrypted: %s\nDecrypted: %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">enc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dec</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">polybii</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">tagstart</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'J'</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">tagstart</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'K'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'Z'</span><span style="color: #0000FF;">-</span><span style="color: #008000;">'J'</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #008000;">"BGWKZQPNDSIOAXEFCLUMTHYVR"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">" ."</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">tagstart</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'A'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">tagstart</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'a'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">26</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">tagstart</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)},</span>
|
||||
<span style="color: #000000;">messages</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"ATTACKATDAWN"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"FLEEATONCE"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #008000;">"The invasion will start on the first of January 2023."</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #000000;">messages</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">],</span><span style="color: #000000;">polybii</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
106
Task/Bifid-cipher/Python/bifid-cipher.py
Normal file
106
Task/Bifid-cipher/Python/bifid-cipher.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"""Bifid cipher. Requires Python >=3.7."""
|
||||
import math
|
||||
import pprint
|
||||
import string
|
||||
|
||||
from itertools import chain
|
||||
from itertools import zip_longest
|
||||
|
||||
from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import Iterator
|
||||
from typing import Tuple
|
||||
from typing import TypeVar
|
||||
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def group(it: Iterable[T], n: int) -> Iterator[Tuple[T, ...]]:
|
||||
"""Return the input iterable split in to `n` equal chunks, padded with `None`."""
|
||||
return zip_longest(*[iter(it)] * n)
|
||||
|
||||
|
||||
Square = Tuple[Tuple[str, ...], ...]
|
||||
|
||||
|
||||
def polybius_square(alphabet: str) -> Square:
|
||||
"""Return the given alphabet as a tuple of tuples, representing a Polybius square."""
|
||||
return tuple(group(alphabet, math.ceil(math.sqrt(len(alphabet)))))
|
||||
|
||||
|
||||
def polybius_map(square: Square) -> Dict[str, Tuple[int, int]]:
|
||||
"""Return a reverse lookup for the given Polybius square."""
|
||||
return {
|
||||
square[i][j]: (i + 1, j + 1)
|
||||
for i in range(len(square))
|
||||
for j in range(len(square))
|
||||
}
|
||||
|
||||
|
||||
def encrypt(message: str, square: Square) -> str:
|
||||
"""Encrypt a plaintext message using a bifid cipher with the given Polybius square."""
|
||||
_map = polybius_map(square)
|
||||
return "".join(
|
||||
square[x - 1][y - 1]
|
||||
for x, y in group(
|
||||
chain.from_iterable(zip(*(_map[c] for c in message if c in _map))),
|
||||
2,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def decrypt(message: str, square: Square) -> str:
|
||||
"""Decrypt a ciphertext message using a bifid cipher with the given Polybius square."""
|
||||
_map = polybius_map(square)
|
||||
return "".join(
|
||||
square[x - 1][y - 1]
|
||||
for x, y in zip(
|
||||
*group(
|
||||
chain.from_iterable((_map[c] for c in message if c in _map)),
|
||||
len(message),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def normalize(message: str) -> str:
|
||||
"""Normalize a message for the typical Polybius square."""
|
||||
return message.upper().replace("J", "I")
|
||||
|
||||
|
||||
TYPICAL_POLYBIUS_SQUARE = polybius_square(
|
||||
alphabet="".join(c for c in string.ascii_uppercase if c != "J")
|
||||
)
|
||||
|
||||
|
||||
EXAMPLE_POLYBIUS_SQUARE = polybius_square(
|
||||
alphabet="BGWKZQPNDSIOAXEFCLUMTHYVR",
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
test_cases = [
|
||||
("ATTACKATDAWN", TYPICAL_POLYBIUS_SQUARE), # 1
|
||||
("FLEEATONCE", EXAMPLE_POLYBIUS_SQUARE), # 2
|
||||
("FLEEATONCE", TYPICAL_POLYBIUS_SQUARE), # 3
|
||||
(
|
||||
normalize("The invasion will start on the first of January"),
|
||||
polybius_square(alphabet="PLAYFIREXMBCDGHKNOQSTUVWZ"),
|
||||
),
|
||||
(
|
||||
"The invasion will start on the first of January".upper(),
|
||||
polybius_square(alphabet=string.ascii_uppercase + string.digits),
|
||||
),
|
||||
]
|
||||
|
||||
for message, square in test_cases:
|
||||
pprint.pprint(square)
|
||||
print("Message :", message)
|
||||
print("Encrypted:", encrypt(message, square))
|
||||
print("Decrypted:", decrypt(encrypt(message, square), square))
|
||||
print("")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
24
Task/Bifid-cipher/Raku/bifid-cipher.raku
Normal file
24
Task/Bifid-cipher/Raku/bifid-cipher.raku
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
sub polybius ($text) {
|
||||
my $n = $text.chars.sqrt.narrow;
|
||||
$text.comb.kv.map: { $^v => ($^k % $n, $k div $n).join: ' ' }
|
||||
}
|
||||
|
||||
sub encrypt ($message, %poly) {
|
||||
%poly.invert.hash{(flat reverse [Z] %poly{$message.comb}».words).batch(2)».reverse».join: ' '}.join
|
||||
}
|
||||
|
||||
sub decrypt ($message, %poly) {
|
||||
%poly.invert.hash{reverse [Z] (reverse flat %poly{$message.comb}».words».reverse).batch($message.chars)}.join
|
||||
}
|
||||
|
||||
|
||||
for 'ABCDEFGHIKLMNOPQRSTUVWXYZ', 'ATTACKATDAWN',
|
||||
'BGWKZQPNDSIOAXEFCLUMTHYVR', 'FLEEATONCE',
|
||||
(flat '_', '.', 'A'..'Z', 'a'..'z', 0..9).pick(*).join, 'The invasion will start on the first of January 2023.'.subst(/' '/, '_', :g)
|
||||
-> $polybius, $message {
|
||||
my %polybius = polybius $polybius;
|
||||
say "\nUsing polybius:\n\t" ~ $polybius.comb.batch($polybius.chars.sqrt.narrow).join: "\n\t";
|
||||
say "\n Message : $message";
|
||||
say "Encrypted : " ~ my $encrypted = encrypt $message, %polybius;
|
||||
say "Decrypted : " ~ decrypt $encrypted, %polybius;
|
||||
}
|
||||
58
Task/Bifid-cipher/Wren/bifid-cipher.wren
Normal file
58
Task/Bifid-cipher/Wren/bifid-cipher.wren
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import "./str" for Str
|
||||
import "./seq" for Lst
|
||||
|
||||
class Bifid {
|
||||
static encrypt(polybius, message) {
|
||||
message = Str.upper(message).replace("J", "I")
|
||||
var rows = []
|
||||
var cols = []
|
||||
for (c in message) {
|
||||
var ix = polybius.indexOf(c)
|
||||
if (ix == -1) continue
|
||||
rows.add((ix/5).floor + 1)
|
||||
cols.add((ix%5) + 1)
|
||||
}
|
||||
var s = ""
|
||||
for (pair in Lst.chunks(rows + cols, 2)) {
|
||||
var ix = (pair[0] - 1) * 5 + pair[1] - 1
|
||||
s = s + polybius[ix]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
static decrypt(polybius, message) {
|
||||
var rows = []
|
||||
var cols = []
|
||||
for (c in message) {
|
||||
var ix = polybius.indexOf(c)
|
||||
rows.add((ix/5).floor + 1)
|
||||
cols.add((ix%5) + 1)
|
||||
}
|
||||
var lines = Lst.flatten(Lst.zip(rows, cols))
|
||||
var count = lines.count/2
|
||||
rows = lines[0...count]
|
||||
cols = lines[count..-1]
|
||||
var s = ""
|
||||
for (i in 0...count) {
|
||||
var ix = (rows[i] - 1) * 5 + cols[i] - 1
|
||||
s = s + polybius[ix]
|
||||
}
|
||||
return s
|
||||
}
|
||||
}
|
||||
var poly1 = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
|
||||
var poly2 = "BGWKZQPNDSIOAXEFCLUMTHYVR"
|
||||
var poly3 = "PLAYFIREXMBCDGHKNOQSTUVWZ"
|
||||
var polys = [poly1, poly2, poly2, poly3]
|
||||
var msg1 = "ATTACKATDAWN"
|
||||
var msg2 = "FLEEATONCE"
|
||||
var msg3 = "The invasion will start on the first of January"
|
||||
var msgs = [msg1, msg2, msg1, msg3]
|
||||
for (i in 0...msgs.count) {
|
||||
var encrypted = Bifid.encrypt(polys[i], msgs[i])
|
||||
var decrypted = Bifid.decrypt(polys[i], encrypted)
|
||||
System.print("Message : %(msgs[i])")
|
||||
System.print("Encrypted : %(encrypted)")
|
||||
System.print("Decrypted : %(decrypted)")
|
||||
if (i < msgs.count-1) System.print()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue