Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
30
Task/Bifid-cipher/Ada/bifid-cipher.adb
Normal file
30
Task/Bifid-cipher/Ada/bifid-cipher.adb
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;
|
||||
|
|
@ -9,104 +9,104 @@ typedef std::pair<int32_t, int32_t> point;
|
|||
|
||||
class Bifid {
|
||||
public:
|
||||
Bifid(const int32_t n, std::string_view text) {
|
||||
if ( text.length() != n * n ) {
|
||||
throw std::invalid_argument("Incorrect length of text");
|
||||
}
|
||||
Bifid(const int32_t n, std::string_view text) {
|
||||
if ( text.length() != n * n ) {
|
||||
throw std::invalid_argument("Incorrect length of text");
|
||||
}
|
||||
|
||||
grid.resize(n);
|
||||
for ( uint64_t i = 0; i < grid.size(); i++ ) {
|
||||
grid[i].resize(n);
|
||||
}
|
||||
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 ( const char& ch : text ) {
|
||||
grid[row][col] = ch;
|
||||
coordinates[ch] = point(row, col);
|
||||
col += 1;
|
||||
if ( col == n ) {
|
||||
col = 0;
|
||||
row += 1;
|
||||
}
|
||||
}
|
||||
int32_t row = 0;
|
||||
int32_t col = 0;
|
||||
for ( const 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'];
|
||||
}
|
||||
}
|
||||
if ( n == 5 ) {
|
||||
coordinates['J'] = coordinates['I'];
|
||||
}
|
||||
}
|
||||
|
||||
std::string encrypt(std::string_view text) {
|
||||
std::vector<int32_t> row_one, row_two;
|
||||
for ( const char& ch : text ) {
|
||||
point coordinate = coordinates[ch];
|
||||
row_one.push_back(coordinate.first);
|
||||
row_two.push_back(coordinate.second);
|
||||
}
|
||||
std::string encrypt(std::string_view text) {
|
||||
std::vector<int32_t> row_one, row_two;
|
||||
for ( const 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;
|
||||
}
|
||||
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(std::string_view text) {
|
||||
std::vector<int32_t> row;
|
||||
for ( const char& ch : text ) {
|
||||
point coordinate = coordinates[ch];
|
||||
row.push_back(coordinate.first);
|
||||
row.push_back(coordinate.second);
|
||||
}
|
||||
std::string decrypt(std::string_view text) {
|
||||
std::vector<int32_t> row;
|
||||
for ( const 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;
|
||||
}
|
||||
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 ( const std::vector<char>& row : grid ) {
|
||||
for ( const char& ch : row ) {
|
||||
std::cout << ch << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
void display() const {
|
||||
for ( const std::vector<char>& row : grid ) {
|
||||
for ( const char& ch : row ) {
|
||||
std::cout << ch << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::vector<std::vector<char>> grid;
|
||||
std::unordered_map<char, point> coordinates;
|
||||
std::vector<std::vector<char>> grid;
|
||||
std::unordered_map<char, point> coordinates;
|
||||
};
|
||||
|
||||
void runTest(Bifid& bifid, std::string_view 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;
|
||||
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_view message1 = "ATTACKATDAWN";
|
||||
const std::string_view message2 = "FLEEATONCE";
|
||||
const std::string_view message3 = "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY";
|
||||
const std::string_view message1 = "ATTACKATDAWN";
|
||||
const std::string_view message2 = "FLEEATONCE";
|
||||
const std::string_view message3 = "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY";
|
||||
|
||||
Bifid bifid1(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ");
|
||||
Bifid bifid2(5, "BGWKZQPNDSIOAXEFCLUMTHYVR");
|
||||
Bifid bifid1(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ");
|
||||
Bifid bifid2(5, "BGWKZQPNDSIOAXEFCLUMTHYVR");
|
||||
|
||||
runTest(bifid1, message1);
|
||||
runTest(bifid2, message2);
|
||||
runTest(bifid2, message1);
|
||||
runTest(bifid1, message2);
|
||||
runTest(bifid1, message1);
|
||||
runTest(bifid2, message2);
|
||||
runTest(bifid2, message1);
|
||||
runTest(bifid1, message2);
|
||||
|
||||
Bifid bifid3(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
runTest(bifid3, message3);
|
||||
Bifid bifid3(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
|
||||
runTest(bifid3, message3);
|
||||
}
|
||||
|
|
|
|||
46
Task/Bifid-cipher/Crystal/bifid-cipher.cr
Normal file
46
Task/Bifid-cipher/Crystal/bifid-cipher.cr
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
enum BifidOp
|
||||
Encode
|
||||
Decode
|
||||
end
|
||||
|
||||
def bifid_encode (message, alphabet, op : BifidOp = :encode)
|
||||
square = alphabet.chars
|
||||
side = Math.isqrt(square.size)
|
||||
raise "alphabet not a square" unless side*side == square.size
|
||||
chars = message.chars
|
||||
raise "incomplete alphabet" unless chars.all?(&.in? square)
|
||||
|
||||
coords = chars.flat_map {|ch| [*square.index!(ch).divmod(side)] }
|
||||
|
||||
coords = if op.encode?
|
||||
(0...coords.size).step(2).map {|i| coords[i] }.to_a +
|
||||
(1...coords.size).step(2).map {|i| coords[i] }.to_a
|
||||
else
|
||||
half = coords.size//2
|
||||
coords[...half].zip(coords[half..]).map {|c1, c2|
|
||||
[c1, c2]
|
||||
}.flatten
|
||||
end
|
||||
coords.each_slice(2).map {|(row, col)|
|
||||
square[row * side + col]
|
||||
}.join
|
||||
end
|
||||
|
||||
poly1 = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
|
||||
poly2 = "BGWKZQPNDSIOAXEFCLUMTHYVR"
|
||||
superpoly = (' '..'~').join + "¡éßñø"
|
||||
|
||||
attack = "ATTACKATDAWN"
|
||||
flee = "FLEEATONCE"
|
||||
invasion = "The invasion will start on the first of January".upcase.tr("J", "I").delete("^A-Z")
|
||||
ataque = "¡Attack on 1/1 at 23:59, señor!"
|
||||
|
||||
[{attack, poly1}, {flee, poly2}, {attack, poly2},
|
||||
{invasion, poly1}, {ataque, superpoly}].each do |message, alphabet|
|
||||
encoded = bifid_encode(message, alphabet)
|
||||
decoded = bifid_encode(encoded, alphabet, :decode)
|
||||
puts "Message: #{message} #{alphabet.size > 80 ? "\n" : " "}- Alphabet: #{alphabet}"
|
||||
puts "Encoded: #{encoded}"
|
||||
puts "Decoded: #{decoded}"
|
||||
puts
|
||||
end
|
||||
|
|
@ -18,13 +18,13 @@ model
|
|||
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
|
||||
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
|
||||
|
|
|
|||
219
Task/Bifid-cipher/Fortran/bifid-cipher.f
Normal file
219
Task/Bifid-cipher/Fortran/bifid-cipher.f
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
!
|
||||
! Bifid cipher
|
||||
! tested with Intel ifx (IFX) 2025.2.1 20250806 on Kubuntu 25.10
|
||||
! GNU Fortran (Ubuntu 15.2.0-4ubuntu4) 15.2.0 on Kubuntu 25.10
|
||||
! VSI Fortran x86-64 V8.6-001 on OpenVMS x86_64 V9.2-3
|
||||
! No Non-standard features used, should compile on any fairly recent Fortran.
|
||||
!
|
||||
! U.B., October 2025
|
||||
!==============================================================================
|
||||
|
||||
program BifidCipher
|
||||
|
||||
implicit none
|
||||
|
||||
! Constants:
|
||||
|
||||
integer, parameter :: nTests = 6 ! NUmber of different test messages
|
||||
integer, parameter :: maxLen=100 ! Maximum length of any test message
|
||||
|
||||
! Instead of drawing the Polybius squares, we only define the alphabet to applied and calculate
|
||||
! row and column number on the fly when needed.
|
||||
! If necessary, the Encrypt and Decrypt subroutines extend the alphabets using "SpareAlpha"
|
||||
! until the total length of the extended alphabet is a square number. This is important because
|
||||
! otherwise the enccrypt or decrypt algorithm may calculate a row/column combination that is
|
||||
! not used by the actual alphabet.
|
||||
|
||||
! The alphabet as shown in the task description has no J.
|
||||
character (len=*), parameter :: Alphabet_no_J ='ABCDEFGHIKLMNOPQRSTUVWXYZ'
|
||||
|
||||
! The alphabet of capital letters as used in most western languages
|
||||
character (len=*), parameter :: Alphabet_With_J ='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
! The square in the wikipedia article in 1 long string:
|
||||
character (len=*), parameter :: AlternateAlphabet = 'BGWKZQPNDSIOAXEFCLUMTHYVR'
|
||||
|
||||
! Standard Alphabet with CAPITAL and small letters
|
||||
character (len=*), parameter :: Alphabet_withSmallLetters = &
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
! Printable spare characters to extend alphabets so the total length becomes the
|
||||
! next larger square number > the alphabet's length
|
||||
character (len=*), parameter :: SpareAlpha = '1234567890!"§$%&/()=' ! omitted ! and "
|
||||
|
||||
! Variables:
|
||||
|
||||
character (len=maxLen) :: MsgToEncrypt (nTests), EncryptedMsg (nTests), DecryptedMsg (nTests)
|
||||
|
||||
integer :: ColWidth ! Is variable and depends on length of the used alphabet
|
||||
|
||||
integer :: i, lx
|
||||
|
||||
! The test strings: (1) is from the task description, (2) is from the Wikipedia Article, (3) is
|
||||
! the additional message as presented in the task description
|
||||
MsgToEncrypt(1) = 'ATTACKATDAWN'
|
||||
MsgToEncrypt(2) = 'FLEEATONCE'
|
||||
MsgToEncrypt(3) = 'THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY'
|
||||
|
||||
! Same text, with both small and capital letters, to be used with an extended Polybius square
|
||||
MsgToEncrypt(4) = 'AttackAtDawn'
|
||||
MsgToEncrypt(5) = 'FleeAtOnce'
|
||||
MsgToEncrypt(6) = 'TheInvasionWillStartOnTheFirstOfJanuary'
|
||||
|
||||
print '(A/)', 'Using the alphabet and Polybius square without "J"'
|
||||
call PrintSquare (Alphabet_no_J)
|
||||
do i=1, nTests/2
|
||||
lx = len_trim (MsgToEncrypt(i))
|
||||
call encrypt (MsgToEncrypt(i)(:lx) , EncryptedMsg (i) , Alphabet_no_J)
|
||||
call decrypt (EncryptedMsg(i) (:lx), DecryptedMsg (i) , Alphabet_no_J)
|
||||
print '(A, " => ", A, " => ", A)', MsgToEncrypt(i)(:lx), EncryptedMsg (i)(:lx), DecryptedMsg (i)(:lx)
|
||||
enddo
|
||||
|
||||
print '(/A/)', 'Using the extended alphabet and Polybius square that includes "J"'
|
||||
call PrintSquare (Alphabet_with_J)
|
||||
do i=1, nTests/2
|
||||
lx = len_trim (MsgToEncrypt(i))
|
||||
call encrypt (MsgToEncrypt(i)(:lx) , EncryptedMsg (i) , Alphabet_with_J)
|
||||
call decrypt (EncryptedMsg(i) (:lx), DecryptedMsg (i) , Alphabet_with_J)
|
||||
print '(A, " => ", A, " => ", A)', MsgToEncrypt(i)(:lx), EncryptedMsg (i)(:lx), DecryptedMsg (i)(:lx)
|
||||
end do
|
||||
|
||||
print '(/A/)', 'Using the alphabet and Polybius square as shown in the Wikipedia article (no J!)'
|
||||
call PrintSquare (AlternateAlphabet)
|
||||
do i=1, nTests/2
|
||||
lx = len_trim (MsgToEncrypt(i))
|
||||
call encrypt (MsgToEncrypt(i)(:lx) , EncryptedMsg (i) , AlternateAlphabet)
|
||||
call decrypt (EncryptedMsg(i) (:lx), DecryptedMsg (i) , AlternateAlphabet)
|
||||
print '(A, " => ", A, " => ", A)', MsgToEncrypt(i)(:lx), EncryptedMsg (i)(:lx), DecryptedMsg (i)(:lx)
|
||||
end do
|
||||
|
||||
print '(/A/)', 'Using the extended alphabet with both upper case and lower case letters, including J and j'
|
||||
call PrintSquare (Alphabet_withSmallLetters)
|
||||
do i=nTests/2+1, nTests
|
||||
lx = len_trim (MsgToEncrypt(i))
|
||||
call encrypt (MsgToEncrypt(i)(:lx) , EncryptedMsg (i) , Alphabet_withSmallLetters)
|
||||
call decrypt (EncryptedMsg(i) (:lx), DecryptedMsg (i) , Alphabet_withSmallLetters)
|
||||
print '(A, " => ", A, " => ", A)', MsgToEncrypt(i)(:lx), EncryptedMsg (i)(:lx), DecryptedMsg (i)(:lx)
|
||||
end do
|
||||
|
||||
contains
|
||||
|
||||
!======================
|
||||
! Encode a given string
|
||||
! ======================
|
||||
subroutine encrypt (inString,outString, argAlphabet)
|
||||
character (len=*), intent(in) :: argAlphabet
|
||||
character (len=*), intent(in) :: inString
|
||||
character (len=*), intent(out) :: outString
|
||||
character (len=100) :: Alphabet
|
||||
|
||||
integer :: idxLine(2*maxLen)
|
||||
integer :: l, ii, idx, row, col
|
||||
|
||||
! Calculate required column width: so that ColWidth^2 >= (length of Alphabet)
|
||||
Alphabet = argAlphabet
|
||||
l = len_trim(alphabet)
|
||||
ColWidth = 1
|
||||
do while (ColWidth*ColWidth .lt. l)
|
||||
ColWidth = ColWidth + 1
|
||||
end do
|
||||
if (ColWidth .gt.8) stop 'ERROR: Cannot handle Alphabets with more than 64 characters.'
|
||||
! Provide some printable chars until the length is a square number
|
||||
Alphabet (l+1:) = SpareAlpha
|
||||
|
||||
l = len_trim (inString)
|
||||
if (l .gt. len(outString)) stop 'ERROR: not enough storage space for encrypt result string.'
|
||||
|
||||
do ii=1, l
|
||||
! print *, ' ii = ', ii, ' instring(ii) = ', inString(ii:ii)
|
||||
idx = index (Alphabet, inString(ii:ii))
|
||||
if (idx .eq. 0) idx = index (Alphabet, char(ichar(instring(ii:ii))-1)) ! J=I, j=i, just in case
|
||||
row = (idx+ColWidth-1) / ColWidth ! e.g. 'A' ...'E', idx=1...5, row=(5...9)/5 = 1, col = 1...5
|
||||
col = 1+mod (idx+ColWidth-1, ColWidth) ! e.g. 'F' ...'K', idx=6...10, row=(10...14)/5 = 2, col = 1...5
|
||||
idxLine (ii) = row
|
||||
idxLine (ii+l) = col
|
||||
end do
|
||||
|
||||
do ii=1, l
|
||||
idx = 10*idxLine(1+2*(ii-1)) + idxLine (2+2*(ii-1))
|
||||
row = idxLine(1+2*(ii-1))
|
||||
col = idxLine (2+2*(ii-1))
|
||||
idx = ColWidth*(row-1) + col
|
||||
outString (ii:ii) = alphabet (idx:idx)
|
||||
enddo
|
||||
end subroutine encrypt
|
||||
|
||||
|
||||
!======================
|
||||
! Decode a given string
|
||||
!======================
|
||||
subroutine decrypt (inString,outString, argAlphabet)
|
||||
|
||||
character (len=*), intent(in) :: inString
|
||||
character (len=*), intent(out) :: outString
|
||||
character (len=*), intent(in) :: argAlphabet
|
||||
|
||||
character (len=100) :: Alphabet
|
||||
|
||||
integer :: idxLine(2*maxLen)
|
||||
integer :: l, ii, idx, row, col
|
||||
|
||||
! Calculate required column width: so that ColWidth^2 >= (length of Alphabet)
|
||||
Alphabet = argAlphabet
|
||||
l = len_trim(alphabet)
|
||||
ColWidth = 1
|
||||
do while (ColWidth*ColWidth .lt. l)
|
||||
ColWidth = ColWidth + 1
|
||||
end do
|
||||
|
||||
! Append some spare characters so that the square is completely filled without undefined fields
|
||||
Alphabet (l+1:) = SpareAlpha
|
||||
|
||||
l = len_trim (inString)
|
||||
if (l .gt. len(outString)) stop 'ERROR: not enough storage space for decrypt result string.'
|
||||
|
||||
do ii=1, l
|
||||
idx = index (Alphabet, inString(ii:ii))
|
||||
row = (idx+ColWidth-1) / ColWidth ! idx 1...5 is row 1, 6...10 is row 2 etc
|
||||
col = 1+mod (idx+ColWidth-1, ColWidth) ! so that 21...29 -> 1...9 etc.
|
||||
idxLine (1+2*(ii-1)) = row
|
||||
idxLine (2+2*(ii-1)) = col
|
||||
end do
|
||||
|
||||
do ii=1, l
|
||||
row = idxLine (ii)
|
||||
col = idxLine (ii+l)
|
||||
idx = ColWidth*(row-1) + col
|
||||
outString (ii:ii) = alphabet (idx:idx)
|
||||
end do
|
||||
|
||||
end subroutine decrypt
|
||||
|
||||
|
||||
! ================================================================================
|
||||
! Print the resulting Polybius square based on the alphabet used for encode/decode
|
||||
! ================================================================================
|
||||
subroutine PrintSquare (Alphabet)
|
||||
character (len=*), intent(in) :: Alphabet
|
||||
integer:: ii, l
|
||||
|
||||
l = len_trim(alphabet)
|
||||
ColWidth = 1
|
||||
do while (ColWidth*ColWidth .lt. l)
|
||||
ColWidth = ColWidth + 1
|
||||
end do
|
||||
print '("The alphabet has a length of ", I0, " so it requires the square size of ", I0, "x", I0 /)' , l, ColWidth, ColWidth
|
||||
|
||||
do ii=1, ColWidth*ColWidth
|
||||
if (ii .le. l) then
|
||||
write (*, '(A2)', advance='no') Alphabet(ii:ii)
|
||||
else
|
||||
write (*, '(A2)', advance='no') SpareAlpha (ii-l:ii-l) ! Use spares to complete the square
|
||||
endif
|
||||
if (mod (ii, ColWidth) .eq. 0) print * ! End of line
|
||||
end do
|
||||
print * ! one extra blank line
|
||||
end subroutine PrintSquare
|
||||
|
||||
|
||||
end program BifidCipher
|
||||
|
|
@ -5,176 +5,176 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
squareRosetta [][]byte = [][]byte{ //rosettacode
|
||||
{'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'},
|
||||
{'J', '1', '2', '3', '4'},
|
||||
}
|
||||
squareRosetta [][]byte = [][]byte{ //rosettacode
|
||||
{'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'},
|
||||
{'J', '1', '2', '3', '4'},
|
||||
}
|
||||
|
||||
squareWikipedia [][]byte = [][]byte{ // wikipedia
|
||||
squareWikipedia [][]byte = [][]byte{ // wikipedia
|
||||
|
||||
{'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'},
|
||||
{'J', '1', '2', '3', '4'},
|
||||
}
|
||||
{'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'},
|
||||
{'J', '1', '2', '3', '4'},
|
||||
}
|
||||
|
||||
textRosetta string = "0ATTACKATDAWN"
|
||||
textRosettaEncoded string = "DQBDAXDQPDQH" // only for test
|
||||
textWikipedia string = "FLEEATONCE"
|
||||
textWikipediaEncoded string = "UAEOLWRINS" // only for test
|
||||
textTest string = "The invasion will start on the first of January"
|
||||
textTextEncoded string = "RASOAQXFIOORXESXADETSWLTNIAZQOISBRGBALY" // only for test
|
||||
textRosetta string = "0ATTACKATDAWN"
|
||||
textRosettaEncoded string = "DQBDAXDQPDQH" // only for test
|
||||
textWikipedia string = "FLEEATONCE"
|
||||
textWikipediaEncoded string = "UAEOLWRINS" // only for test
|
||||
textTest string = "The invasion will start on the first of January"
|
||||
textTextEncoded string = "RASOAQXFIOORXESXADETSWLTNIAZQOISBRGBALY" // only for test
|
||||
)
|
||||
|
||||
type koord struct {
|
||||
X byte
|
||||
Y byte
|
||||
X byte
|
||||
Y byte
|
||||
}
|
||||
|
||||
func (k *koord) LessThen(other *koord) bool {
|
||||
if k.Y > other.Y {
|
||||
return false
|
||||
}
|
||||
if k.Y < other.Y {
|
||||
return true
|
||||
}
|
||||
if k.X < other.X {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
if k.Y > other.Y {
|
||||
return false
|
||||
}
|
||||
if k.Y < other.Y {
|
||||
return true
|
||||
}
|
||||
if k.X < other.X {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (k *koord) EqualTo(other koord) bool {
|
||||
if k.X == other.X && k.Y == other.Y {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
if k.X == other.X && k.Y == other.Y {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var encryptMap map[byte]koord
|
||||
var decryptMap map[koord]byte
|
||||
|
||||
func squareToMaps(square [][]byte) (map[byte]koord, map[koord]byte) {
|
||||
eMap := make(map[byte]koord)
|
||||
dMap := make(map[koord]byte)
|
||||
for x, col := range square {
|
||||
for y, v := range col {
|
||||
eMap[v] = koord{byte(x), byte(y)}
|
||||
dMap[koord{byte(x), byte(y)}] = v
|
||||
eMap := make(map[byte]koord)
|
||||
dMap := make(map[koord]byte)
|
||||
for x, col := range square {
|
||||
for y, v := range col {
|
||||
eMap[v] = koord{byte(x), byte(y)}
|
||||
dMap[koord{byte(x), byte(y)}] = v
|
||||
|
||||
}
|
||||
}
|
||||
return eMap, dMap
|
||||
}
|
||||
}
|
||||
return eMap, dMap
|
||||
}
|
||||
|
||||
func removeSpaceI(text string) string {
|
||||
var n string
|
||||
s := strings.ToUpper(text)
|
||||
for _, b := range []byte(s) {
|
||||
//use only ASCII Characters from A to Z
|
||||
if b < 'A' || b > 'Z' {
|
||||
continue
|
||||
}
|
||||
if b == 'J' {
|
||||
b = 'I'
|
||||
}
|
||||
n = n + string(b)
|
||||
}
|
||||
return n
|
||||
var n string
|
||||
s := strings.ToUpper(text)
|
||||
for _, b := range []byte(s) {
|
||||
//use only ASCII Characters from A to Z
|
||||
if b < 'A' || b > 'Z' {
|
||||
continue
|
||||
}
|
||||
if b == 'J' {
|
||||
b = 'I'
|
||||
}
|
||||
n = n + string(b)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func removeSpace(text string, square map[byte]koord) string {
|
||||
var n string
|
||||
//to UpperCase and then remove all Spaces an Characters witch are not in square
|
||||
s := strings.ReplaceAll(strings.ToUpper(text), " ", "")
|
||||
for _, b := range []byte(s) {
|
||||
_, ok := square[b]
|
||||
if ok {
|
||||
n = n + string(b)
|
||||
}
|
||||
}
|
||||
return n
|
||||
var n string
|
||||
//to UpperCase and then remove all Spaces an Characters witch are not in square
|
||||
s := strings.ReplaceAll(strings.ToUpper(text), " ", "")
|
||||
for _, b := range []byte(s) {
|
||||
_, ok := square[b]
|
||||
if ok {
|
||||
n = n + string(b)
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func encrypt(text string, emap map[byte]koord, dmap map[koord]byte) string {
|
||||
text = removeSpace(text, emap)
|
||||
var row0, row1 []byte
|
||||
for _, b := range []byte(text) {
|
||||
xy := emap[b]
|
||||
row0 = append(row0, xy.X)
|
||||
row1 = append(row1, xy.Y)
|
||||
}
|
||||
row0 = append(row0, row1...)
|
||||
text = removeSpace(text, emap)
|
||||
var row0, row1 []byte
|
||||
for _, b := range []byte(text) {
|
||||
xy := emap[b]
|
||||
row0 = append(row0, xy.X)
|
||||
row1 = append(row1, xy.Y)
|
||||
}
|
||||
row0 = append(row0, row1...)
|
||||
|
||||
var s string
|
||||
for i := 0; i < len(row0); i += 2 {
|
||||
s = s + string(dmap[koord{row0[i], row0[i+1]}])
|
||||
}
|
||||
return s
|
||||
var s string
|
||||
for i := 0; i < len(row0); i += 2 {
|
||||
s = s + string(dmap[koord{row0[i], row0[i+1]}])
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func decrypt(text string, emap map[byte]koord, dmap map[koord]byte) string {
|
||||
text = removeSpace(text, emap)
|
||||
k := make([]koord, len(text))
|
||||
text = removeSpace(text, emap)
|
||||
k := make([]koord, len(text))
|
||||
|
||||
for i, b := range []byte(text) {
|
||||
k[i] = emap[b]
|
||||
}
|
||||
for i, b := range []byte(text) {
|
||||
k[i] = emap[b]
|
||||
}
|
||||
|
||||
kl := make([]byte, len(k)*2)
|
||||
i := int(0)
|
||||
for _, ki := range k {
|
||||
kl[i] = ki.X
|
||||
kl[i+1] = ki.Y
|
||||
i += 2
|
||||
}
|
||||
l := len(kl) / 2
|
||||
k1 := kl[:l]
|
||||
k2 := kl[l:]
|
||||
var s string
|
||||
kl := make([]byte, len(k)*2)
|
||||
i := int(0)
|
||||
for _, ki := range k {
|
||||
kl[i] = ki.X
|
||||
kl[i+1] = ki.Y
|
||||
i += 2
|
||||
}
|
||||
l := len(kl) / 2
|
||||
k1 := kl[:l]
|
||||
k2 := kl[l:]
|
||||
var s string
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
s = s + string(dmap[koord{k1[i], k2[i]}])
|
||||
}
|
||||
return s
|
||||
for i := 0; i < l; i++ {
|
||||
s = s + string(dmap[koord{k1[i], k2[i]}])
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
encryptMap, decryptMap = squareToMaps(squareRosetta)
|
||||
fmt.Println("from Rosettacode")
|
||||
fmt.Println("original:\t", textRosetta)
|
||||
s := encrypt(textRosetta, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
encryptMap, decryptMap = squareToMaps(squareRosetta)
|
||||
fmt.Println("from Rosettacode")
|
||||
fmt.Println("original:\t", textRosetta)
|
||||
s := encrypt(textRosetta, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
|
||||
fmt.Println("from Wikipedia")
|
||||
encryptMap, decryptMap = squareToMaps(squareWikipedia)
|
||||
fmt.Println("original:\t", textWikipedia)
|
||||
s = encrypt(textWikipedia, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
fmt.Println("from Wikipedia")
|
||||
encryptMap, decryptMap = squareToMaps(squareWikipedia)
|
||||
fmt.Println("original:\t", textWikipedia)
|
||||
s = encrypt(textWikipedia, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
|
||||
encryptMap, decryptMap = squareToMaps(squareWikipedia)
|
||||
fmt.Println("from Rosettacode long part")
|
||||
fmt.Println("original:\t", textTest)
|
||||
s = encrypt(textTest, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
// Wenn der Text eine ungerade Anzahl Buchstaben hat, funktioniert der Algorithmus nicht!!!
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
encryptMap, decryptMap = squareToMaps(squareWikipedia)
|
||||
fmt.Println("from Rosettacode long part")
|
||||
fmt.Println("original:\t", textTest)
|
||||
s = encrypt(textTest, encryptMap, decryptMap)
|
||||
fmt.Println("codiert:\t", s)
|
||||
// Wenn der Text eine ungerade Anzahl Buchstaben hat, funktioniert der Algorithmus nicht!!!
|
||||
s = decrypt(s, encryptMap, decryptMap)
|
||||
fmt.Println("and back:\t", s)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,101 +7,101 @@ 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();
|
||||
}
|
||||
|
||||
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 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>();
|
||||
|
||||
Arrays.stream(grid).forEach( row -> System.out.println(Arrays.toString(row)) );
|
||||
}
|
||||
|
||||
private char[][] grid;
|
||||
private Map<Character, Point> coordinates = new HashMap<Character, Point>();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,64 @@
|
|||
module Bifid_cipher (f, code$) {
|
||||
n=sqrt(len(code$))
|
||||
print #f," ";
|
||||
for i=1 to n
|
||||
print #f, i+" ";
|
||||
next
|
||||
print #f
|
||||
for i=0 to n-1
|
||||
Print #f, (i+1)+" "+STR$(mid$(code$,1+i*n, n),STRING$("@ ", 5))
|
||||
next
|
||||
tables=lambda (a$)->{
|
||||
n=sqrt(len(a$))
|
||||
a=list
|
||||
for i=1 to len(a$)
|
||||
append a, mid$(a$,i, 1):=((i-1) mod n+1, (i-1) div n+1 )
|
||||
next
|
||||
b=list
|
||||
m=each(a)
|
||||
while m
|
||||
z=eval(m)
|
||||
append b, z#val$(1)+z#val$(0):=eval$(m!)
|
||||
end while
|
||||
=a, b
|
||||
}(code$)
|
||||
encode= lambda (a, b)->{
|
||||
=lambda a,b (mess as string) -> {
|
||||
document code$
|
||||
for n=1 to 0
|
||||
for i=1 to len(mess)
|
||||
q=mid$(mess, i,1)
|
||||
if not exist(a, q) then
|
||||
if q="J" then q="I" else q="A"
|
||||
end if
|
||||
code$=a(q)#val$(n)
|
||||
next
|
||||
next
|
||||
document final$
|
||||
for i=1 to len(code$) step 2
|
||||
final$=b$(mid$(code$, i, 2))
|
||||
next
|
||||
= final$
|
||||
}
|
||||
}(!tables)
|
||||
decode= lambda (a, b)->{
|
||||
=lambda a,b (final as string) -> {
|
||||
document code$, mess$
|
||||
for i=1 to len(final)
|
||||
q=a(mid$(final, i, 1))
|
||||
code$=q#val$(1)+q#val$(0)
|
||||
next
|
||||
offset=len(code$) div 2
|
||||
for i=1 to offset
|
||||
mess$=b$(mid$(code$,i,1)+mid$(code$,i+offset,1))
|
||||
next
|
||||
= mess$
|
||||
}
|
||||
}(!tables)
|
||||
Print #f, encode("ATTACKATDAWN")
|
||||
Print #f, decode(encode("ATTACKATDAWN"))="ATTACKATDAWN"
|
||||
Print #f, encode(ucase$(filter$("The invasion will start on the first of January", " ")))
|
||||
Print #f, decode(encode(ucase$(filter$("The invasion will start on the first of January", " "))))
|
||||
n=sqrt(len(code$))
|
||||
print #f," ";
|
||||
for i=1 to n
|
||||
print #f, i+" ";
|
||||
next
|
||||
print #f
|
||||
for i=0 to n-1
|
||||
Print #f, (i+1)+" "+STR$(mid$(code$,1+i*n, n),STRING$("@ ", 5))
|
||||
next
|
||||
tables=lambda (a$)->{
|
||||
n=sqrt(len(a$))
|
||||
a=list
|
||||
for i=1 to len(a$)
|
||||
append a, mid$(a$,i, 1):=((i-1) mod n+1, (i-1) div n+1 )
|
||||
next
|
||||
b=list
|
||||
m=each(a)
|
||||
while m
|
||||
z=eval(m)
|
||||
append b, z#val$(1)+z#val$(0):=eval$(m!)
|
||||
end while
|
||||
=a, b
|
||||
}(code$)
|
||||
encode= lambda (a, b)->{
|
||||
=lambda a,b (mess as string) -> {
|
||||
document code$
|
||||
for n=1 to 0
|
||||
for i=1 to len(mess)
|
||||
q=mid$(mess, i,1)
|
||||
if not exist(a, q) then
|
||||
if q="J" then q="I" else q="A"
|
||||
end if
|
||||
code$=a(q)#val$(n)
|
||||
next
|
||||
next
|
||||
document final$
|
||||
for i=1 to len(code$) step 2
|
||||
final$=b$(mid$(code$, i, 2))
|
||||
next
|
||||
= final$
|
||||
}
|
||||
}(!tables)
|
||||
decode= lambda (a, b)->{
|
||||
=lambda a,b (final as string) -> {
|
||||
document code$, mess$
|
||||
for i=1 to len(final)
|
||||
q=a(mid$(final, i, 1))
|
||||
code$=q#val$(1)+q#val$(0)
|
||||
next
|
||||
offset=len(code$) div 2
|
||||
for i=1 to offset
|
||||
mess$=b$(mid$(code$,i,1)+mid$(code$,i+offset,1))
|
||||
next
|
||||
= mess$
|
||||
}
|
||||
}(!tables)
|
||||
Print #f, encode("ATTACKATDAWN")
|
||||
Print #f, decode(encode("ATTACKATDAWN"))="ATTACKATDAWN"
|
||||
Print #f, encode(ucase$(filter$("The invasion will start on the first of January", " ")))
|
||||
Print #f, decode(encode(ucase$(filter$("The invasion will start on the first of January", " "))))
|
||||
}
|
||||
open "out.txt" for output as #a
|
||||
Bifid_cipher a, "ABCDEFGHIKLMNOPQRSTUVWXYZ"
|
||||
|
|
|
|||
60
Task/Bifid-cipher/Pluto/bifid-cipher.pluto
Normal file
60
Task/Bifid-cipher/Pluto/bifid-cipher.pluto
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
require "table2"
|
||||
|
||||
class bifid
|
||||
static function encrypt(polybius, message)
|
||||
message = message:upper():replace("J", "I")
|
||||
local rows = {}
|
||||
local cols = {}
|
||||
for i = 1, #message do
|
||||
local c = message[i]
|
||||
local ix = polybius:find(c, 1, true)
|
||||
if !ix then continue end
|
||||
rows:insert((ix - 1) // 5 + 1)
|
||||
cols:insert((ix - 1) % 5 + 1)
|
||||
end
|
||||
local s = ""
|
||||
for table.joined(rows, cols):chunk(2) as pair do
|
||||
local ix = (pair[1] - 1) * 5 + pair[2]
|
||||
s ..= polybius[ix]
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
static function decrypt(polybius, message)
|
||||
local rows = {}
|
||||
local cols = {}
|
||||
for i = 1, #message do
|
||||
local c = message[i]
|
||||
local ix = polybius:find(c, 1, true)
|
||||
rows:insert((ix - 1) // 5 + 1)
|
||||
cols:insert((ix - 1) % 5 + 1)
|
||||
end
|
||||
local lines = table.zip(rows, cols):flatten()
|
||||
local count = #lines // 2
|
||||
rows = lines:slice(1, count)
|
||||
cols = lines:slice(count + 1)
|
||||
local s = ""
|
||||
for i = 1, count do
|
||||
local ix = (rows[i] - 1) * 5 + cols[i]
|
||||
s ..= polybius[ix]
|
||||
end
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
local poly1 = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
|
||||
local poly2 = "BGWKZQPNDSIOAXEFCLUMTHYVR"
|
||||
local poly3 = "PLAYFIREXMBCDGHKNOQSTUVWZ"
|
||||
local polys = {poly1, poly2, poly2, poly3}
|
||||
local msg1 = "ATTACKATDAWN"
|
||||
local msg2 = "FLEEATONCE"
|
||||
local msg3 = "The invasion will start on the first of January"
|
||||
local msgs = {msg1, msg2, msg1, msg3}
|
||||
for i = 1, #msgs do
|
||||
local encrypted = bifid.encrypt(polys[i], msgs[i])
|
||||
local decrypted = bifid.decrypt(polys[i], encrypted)
|
||||
print($"Message : {msgs[i]}")
|
||||
print($"Encrypted : {encrypted}")
|
||||
print($"Decrypted : {decrypted}")
|
||||
if i < #msgs then print() end
|
||||
end
|
||||
137
Task/Bifid-cipher/Rebol/bifid-cipher.rebol
Normal file
137
Task/Bifid-cipher/Rebol/bifid-cipher.rebol
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: Bifid cipher"
|
||||
file: %Bifid_cipher.r3
|
||||
url: https://rosettacode.org/wiki/Bifid_cipher
|
||||
]
|
||||
|
||||
make-square: function [
|
||||
{Build a Polybius square from an alphabet string.
|
||||
Returns a block of rows, each row a block of single-character strings.
|
||||
The square is sized ceil(sqrt(len)) x ceil(sqrt(len)), with none padding
|
||||
if the alphabet does not fill the last row exactly.}
|
||||
alphabet [string!]
|
||||
][
|
||||
size: to-integer round/ceiling square-root length? alphabet
|
||||
rows: copy []
|
||||
row: copy []
|
||||
i: 0
|
||||
foreach ch alphabet [
|
||||
append row ch
|
||||
++ i
|
||||
if i = size [
|
||||
append/only rows row
|
||||
row: copy []
|
||||
i: 0
|
||||
]
|
||||
]
|
||||
unless empty? row [ ;; pad final row with none
|
||||
append/dup row none (size - length? row)
|
||||
append/only rows row
|
||||
]
|
||||
new-line/all rows true
|
||||
]
|
||||
|
||||
square-map: function [
|
||||
{Return a map of character -> [row col] (1-based) for the given square.}
|
||||
square [block!]
|
||||
][
|
||||
m: make map! 64
|
||||
r: 1
|
||||
foreach row square [
|
||||
c: 1
|
||||
foreach ch row [
|
||||
if ch [ m/:ch: reduce [r c] ] ; skip none padding
|
||||
++ c
|
||||
]
|
||||
++ r
|
||||
]
|
||||
m
|
||||
]
|
||||
|
||||
encrypt: function [
|
||||
{Encrypt plaintext using the bifid cipher with the given Polybius square.
|
||||
Collects all row coordinates then all column coordinates, pairs them up,
|
||||
and maps each pair back through the square.}
|
||||
message [string!]
|
||||
square [block!]
|
||||
][
|
||||
m: square-map square
|
||||
rows: copy []
|
||||
cols: copy []
|
||||
foreach ch message [
|
||||
if coord: m/:ch [
|
||||
append rows coord/1
|
||||
append cols coord/2
|
||||
]
|
||||
]
|
||||
combined: append copy rows cols ;; [r1 r2 .. rN c1 c2 .. cN]
|
||||
result: copy ""
|
||||
i: 1
|
||||
while [i < length? combined] [
|
||||
r: pick combined i
|
||||
c: pick combined i + 1
|
||||
append result pick (pick square r) c
|
||||
i: i + 2
|
||||
]
|
||||
result
|
||||
]
|
||||
|
||||
decrypt: function [
|
||||
{Decrypt ciphertext using the bifid cipher with the given Polybius square.
|
||||
Splits the coordinate stream into the first half (rows) and second half
|
||||
(cols), zips them, and maps each pair back through the square.}
|
||||
message [string!]
|
||||
square [block!]
|
||||
][
|
||||
m: square-map square
|
||||
coords: copy []
|
||||
foreach ch message [
|
||||
if coord: m/:ch [ repend coords coord ]
|
||||
]
|
||||
half: (length? coords) / 2 ;; split interleaved coords at midpoint
|
||||
rows: copy/part coords half
|
||||
cols: copy/part (skip coords half) half
|
||||
result: copy ""
|
||||
i: 1
|
||||
while [i <= half] [
|
||||
r: rows/:i
|
||||
c: cols/:i
|
||||
append result square/:r/:c
|
||||
++ i
|
||||
]
|
||||
result
|
||||
]
|
||||
|
||||
normalize: func [
|
||||
{Replace J with I for a standard 25-letter Polybius square.}
|
||||
message [string!]
|
||||
][
|
||||
replace/all copy message "J" "I"
|
||||
]
|
||||
|
||||
; --- Polybius squares used in test cases ---
|
||||
|
||||
typical-square: make-square "ABCDEFGHIKLMNOPQRSTUVWXYZ" ;; 25 letters, no J
|
||||
example-square: make-square "BGWKZQPNDSIOAXEFCLUMTHYVR"
|
||||
playfair-square: make-square "PLAYFIREXMBCDGHKNOQSTUVWZ"
|
||||
digits-square: make-square "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
|
||||
; --- Test cases ---
|
||||
|
||||
test-cases: reduce [
|
||||
"ATTACKATDAWN" typical-square
|
||||
"FLEEATONCE" example-square
|
||||
"FLEEATONCE" typical-square
|
||||
normalize "The invasion will start on the first of January" playfair-square
|
||||
"The invasion will start on the first of January" digits-square
|
||||
]
|
||||
|
||||
foreach [msg square] test-cases [
|
||||
probe square
|
||||
enc: encrypt msg square
|
||||
dec: decrypt enc square
|
||||
print ["Message :" msg]
|
||||
print ["Encrypted:" enc]
|
||||
print ["Decrypted:" dec]
|
||||
print ""
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue