Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
117
Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs
Normal file
117
Task/ADFGVX-cipher/C-sharp/adfgvx-cipher.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
const string cypher = "ADFGVX";
|
||||
var N = cypher.Length;
|
||||
var size = N * N;
|
||||
const string symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
Debug.Assert(size == symbols.Length);
|
||||
var square = new int[size];
|
||||
|
||||
for (var i = 0; i < size; i++)
|
||||
{
|
||||
var j = Random.Shared.Next(i + 1);
|
||||
square[i] = square[j];
|
||||
square[j] = i;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{N} x {N} Polybius square:");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($" | {string.Join(' ', cypher.AsEnumerable())}");
|
||||
Console.WriteLine(new string('-', 2 * N + 3));
|
||||
|
||||
for (var row = 0; row < N; row++)
|
||||
{
|
||||
Console.Write($"{cypher[row]} |");
|
||||
|
||||
for (var col = 0; col < N; col++)
|
||||
{
|
||||
Console.Write($" {symbols[square[col + row * N]]}");
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static bool IsSuitableTranspositionKey(string s) =>
|
||||
s.Length >= 7 && s.Length <= 12 && s.Length == s.Distinct().Count() && s.All(symbols.ToLowerInvariant().Contains);
|
||||
|
||||
var keys = File.ReadAllLines("unixdict.txt").Where(IsSuitableTranspositionKey).ToArray();
|
||||
var key = keys[Random.Shared.Next(keys.Length)].ToUpperInvariant();
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"The key is {key}");
|
||||
var plaintext = "ATTACKAT1200AM";
|
||||
Console.WriteLine($"Plaintext: {plaintext}");
|
||||
|
||||
string Encrypt(string plaintext, string key, int[] square)
|
||||
{
|
||||
// Create a lookup table from symbol to fragment
|
||||
var map = (from i in Enumerable.Range(0, size)
|
||||
let k = square[i]
|
||||
let code = cypher[i / N] + "" + cypher[i % N]
|
||||
select (k, code))
|
||||
.ToDictionary(kc => symbols[kc.k], kc => kc.code);
|
||||
|
||||
// Map the plaintext to fragments
|
||||
var e = string.Join("", plaintext.Select(c => map[c]));
|
||||
|
||||
// Determine number of rows
|
||||
var K = key.Length;
|
||||
var rows = (e.Length + K - 1) / K;
|
||||
|
||||
// Pad with spaces
|
||||
e += new string(' ', rows * K - e.Length);
|
||||
|
||||
// Sort the key
|
||||
var order = string.Join("", key.OrderBy(c => c)).Select(c => key.IndexOf(c)).ToArray();
|
||||
|
||||
// Reorder the fragments.
|
||||
e = string.Join("", Enumerable.Range(0, K * rows).Select(i => e[(i / K) * K + order[i % K]]));
|
||||
|
||||
// Transpose
|
||||
e = new([.. from col in Enumerable.Range(0, K)
|
||||
from row in Enumerable.Range(0, rows)
|
||||
select e[row * K + col]]);
|
||||
|
||||
// Read off each column.
|
||||
return string.Join(" ", Enumerable.Range(0, K).Select(col => e.Substring(col * rows, rows).Trim()));
|
||||
}
|
||||
|
||||
var encrypted = Encrypt(plaintext, key, square);
|
||||
Console.WriteLine($"Encrypted: {encrypted}");
|
||||
|
||||
string Decrypt(string encrypted, string key, int[] square)
|
||||
{
|
||||
// Create a lookup table from fragment to symbol
|
||||
var map = (from i in Enumerable.Range(0, size)
|
||||
let k = square[i]
|
||||
let code = cypher[i / N] + "" + cypher[i % N]
|
||||
select (k, code))
|
||||
.ToDictionary(kc => kc.code, kc => symbols[kc.k]);
|
||||
|
||||
// Split into columns
|
||||
var cols = encrypted.Split(' ');
|
||||
|
||||
// Determine number of rows
|
||||
var K = key.Length;
|
||||
var rows = cols.Max(c => c.Length);
|
||||
|
||||
// Pad each column
|
||||
cols = [.. cols.Select(c => c.PadRight(rows))];
|
||||
|
||||
// Transpose
|
||||
string e = new([.. from row in Enumerable.Range(0, rows)
|
||||
from col in Enumerable.Range(0, K)
|
||||
select cols[col][row]]);
|
||||
|
||||
// Sort the key
|
||||
var sorted = string.Join("", key.OrderBy(c => c));
|
||||
var order = key.Select(c => sorted.IndexOf(c)).ToArray();
|
||||
|
||||
// Reorder the fragments
|
||||
e = string.Join("", Enumerable.Range(0, K * rows).Select(i => e[(i / K) * K + order[i % K]])).Trim();
|
||||
|
||||
// Map the fragments to plaintext
|
||||
return string.Join("", Enumerable.Range(0, e.Length / 2).Select(i => map[e.Substring(2 * i, 2)]));
|
||||
}
|
||||
|
||||
var decrypted = Decrypt(encrypted, key, square);
|
||||
Console.WriteLine($"Decrypted: {decrypted}");
|
||||
134
Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js
Normal file
134
Task/ADFGVX-cipher/JavaScript/adfgvx-cipher.js
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
class ADFGVX {
|
||||
/** The WWI German ADFGVX cipher. */
|
||||
constructor(spoly, k, alph = 'ADFGVX') {
|
||||
this.polybius = spoly.toUpperCase().split('');
|
||||
this.pdim = Math.floor(Math.sqrt(this.polybius.length));
|
||||
this.key = k.toUpperCase().split('');
|
||||
this.keylen = this.key.length;
|
||||
this.alphabet = alph.split('');
|
||||
const pairs = [];
|
||||
for (let i = 0; i < this.alphabet.length; i++) {
|
||||
for (let j = 0; j < this.alphabet.length; j++) {
|
||||
pairs.push(this.alphabet[i] + this.alphabet[j]);
|
||||
}
|
||||
}
|
||||
this.encode = {};
|
||||
for (let i = 0; i < this.polybius.length; i++) {
|
||||
this.encode[this.polybius[i]] = pairs[i];
|
||||
}
|
||||
this.decode = {};
|
||||
for (const k in this.encode) {
|
||||
this.decode[this.encode[k]] = k;
|
||||
}
|
||||
}
|
||||
|
||||
encrypt(msg) {
|
||||
/** Encrypt with the ADFGVX cipher. */
|
||||
const chars = [];
|
||||
for (const c of msg.toUpperCase()) {
|
||||
if (this.polybius.includes(c)) {
|
||||
chars.push(this.encode[c]);
|
||||
}
|
||||
}
|
||||
const flatChars = chars.join('').split('');
|
||||
const colvecs = [];
|
||||
for (let i = 0; i < this.keylen; i++) {
|
||||
const currentCol = [];
|
||||
for (let j = i; j < flatChars.length; j += this.keylen) {
|
||||
currentCol.push(flatChars[j]);
|
||||
}
|
||||
colvecs.push([this.key[i], currentCol]);
|
||||
}
|
||||
|
||||
colvecs.sort((a, b) => a[0].localeCompare(b[0]));
|
||||
|
||||
let result = '';
|
||||
for (const a of colvecs) {
|
||||
result += a[1].join('');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
decrypt(cod) {
|
||||
/** Decrypt with the ADFGVX cipher. Does not depend on spacing of encoded text */
|
||||
const chars = [];
|
||||
for (const c of cod) {
|
||||
if (this.alphabet.includes(c)) {
|
||||
chars.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
const sortedkey = [...this.key].sort();
|
||||
const order = [];
|
||||
for (const ch of sortedkey) {
|
||||
order.push(this.key.indexOf(ch));
|
||||
}
|
||||
const originalorder = [];
|
||||
for (const ch of this.key) {
|
||||
originalorder.push(sortedkey.indexOf(ch));
|
||||
}
|
||||
|
||||
const base = Math.floor(chars.length / this.keylen);
|
||||
const extra = chars.length % this.keylen;
|
||||
const strides = order.map((_, i) => base + (extra > i ? 1 : 0));
|
||||
const starts = [0];
|
||||
let sum = 0;
|
||||
for (let i = 0; i < strides.length - 1; i++) {
|
||||
sum += strides[i];
|
||||
starts.push(sum);
|
||||
}
|
||||
const ends = starts.map((start, i) => start + strides[i]);
|
||||
const cols = originalorder.map(i => chars.slice(starts[i], ends[i]));
|
||||
|
||||
const pairs = [];
|
||||
for (let i = 0; i < Math.floor((chars.length - 1) / this.keylen) + 1; i++) {
|
||||
for (let j = 0; j < this.keylen; j++) {
|
||||
if (i * this.keylen + j < chars.length) {
|
||||
pairs.push(cols[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let decoded = '';
|
||||
for (let i = 0; i < pairs.length; i += 2) {
|
||||
decoded += this.decode[pairs[i] + pairs[i + 1]];
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to shuffle an array (Fisher-Yates shuffle)
|
||||
function shuffle(array) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[array[i], array[j]] = [array[j], array[i]];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
async function main() {
|
||||
const PCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.split('');
|
||||
shuffle(PCHARS);
|
||||
const POLYBIUS = PCHARS.join('');
|
||||
|
||||
// Simulate reading from unixdict.txt (replace with your actual file reading method if needed)
|
||||
// For demonstration purposes, using a hardcoded word list:
|
||||
const WORDS = ['ABDEFGHIK', 'JLMNOPQRS', 'TUVWXYZ01', '23456789'];
|
||||
const KEY = WORDS[Math.floor(Math.random() * WORDS.length)];
|
||||
|
||||
|
||||
const SECRET = new ADFGVX(POLYBIUS, KEY);
|
||||
const MESSAGE = 'ATTACKAT1200AM';
|
||||
|
||||
console.log(`Polybius: ${POLYBIUS}, key: ${KEY}`);
|
||||
console.log('Message: ', MESSAGE);
|
||||
|
||||
const ENCODED = SECRET.encrypt(MESSAGE);
|
||||
const DECODED = SECRET.decrypt(ENCODED);
|
||||
|
||||
console.log('Encoded: ', ENCODED);
|
||||
console.log('Decoded: ', DECODED);
|
||||
}
|
||||
|
||||
main();
|
||||
116
Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000
Normal file
116
Task/ADFGVX-cipher/M2000-Interpreter/adfgvx-cipher.m2000
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
Module CheckADFGVX_Cipher {
|
||||
Class cipher {
|
||||
Private:
|
||||
buffer a as byte*36
|
||||
b="ADFGVX"
|
||||
key="ABCDEFGHIJK"
|
||||
orderkey="ABCDEFGHIJK"
|
||||
map=list
|
||||
map2=list
|
||||
module preparemaps {
|
||||
for i=0 to 5
|
||||
jj=0
|
||||
for j=i*6 to j+5
|
||||
.map(chr$(.a[j]))=mid$(.b, i+1,1)+mid$(.b,jj+1, 1)
|
||||
.map2(mid$(.b, i+1,1)+mid$(.b,jj+1, 1))=chr$(.a[j])
|
||||
jj++
|
||||
next
|
||||
next
|
||||
}
|
||||
Public:
|
||||
Module SetRandom (&returnvalue) {
|
||||
return .a, 0:=str$("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
for i=1 to 100
|
||||
c=random(0, 35):d=c
|
||||
while c=d {d=random(0, 35)}
|
||||
byte o=.a[c]
|
||||
.a[c]<=.a[d]
|
||||
.a[d]<=o
|
||||
next
|
||||
returnvalue=chr$(eval$(.a)) ' convert to UTF16LE
|
||||
.preparemaps
|
||||
}
|
||||
Module SetSpecific (that$){
|
||||
return .a, 0:=str$(Ucase$(that$))
|
||||
.preparemaps
|
||||
}
|
||||
Module SetKey (.key as string) {
|
||||
.key<=ucase$(.key)
|
||||
if len(.key)<7 or len(.key)>12 then Error "Key has not proper length"
|
||||
if filter$(.key, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")<>"" then
|
||||
Error "Key has bad letters"
|
||||
end if
|
||||
dim aa(1 to len(.key))
|
||||
for i=1 to len(.key):aa(i)=mid$(.key,i,1):next
|
||||
.orderkey<=aa()#sort()#str$("")
|
||||
}
|
||||
Module Display {
|
||||
Print "The 6 x 6 Polybius square:"
|
||||
Print " | A D F G V X"
|
||||
Print "---------------"
|
||||
for i=0 to 5
|
||||
Print mid$(.b,i+1,1)+" | ";
|
||||
jj=0
|
||||
for j=i*6 to j+5
|
||||
print chr$(.a[j]);" ";
|
||||
jj++
|
||||
next
|
||||
print
|
||||
next
|
||||
Print "Key:";.key
|
||||
}
|
||||
Function Encrypt(p as string) {
|
||||
crypted=""
|
||||
for i=1 to len(p)
|
||||
crypted+=.map$(mid$(p,i,1))
|
||||
next
|
||||
m=1
|
||||
encrypted=""
|
||||
For i = 1 To Len(.key)
|
||||
ch = Mid$(.orderkey, i, 1)
|
||||
For j = Instr(.key, ch) - 1 To Len(crypted) - 1 Step Len(.key)
|
||||
encrypted += Mid$(crypted, j + 1, 1)
|
||||
if m mod 5=0 then encrypted += " "
|
||||
m++
|
||||
Next
|
||||
Next
|
||||
=encrypted
|
||||
}
|
||||
Function Decrypt(p as string) {
|
||||
p=filter$(p, " ")
|
||||
decrypted=""
|
||||
m=1
|
||||
dim b$(len(p))
|
||||
For i = 1 To Len(.key)
|
||||
ch = Mid$(.orderkey, i, 1)
|
||||
For j = Instr(.key, ch) - 1 To Len(p) - 1 Step Len(.key)
|
||||
b$(j)=mid$(p, m, 1)
|
||||
m++
|
||||
Next
|
||||
Next
|
||||
for i=0 to len(b$())-1 step 2
|
||||
decrypted+=.map2(b$(i)+b$(i+1))
|
||||
next
|
||||
=decrypted
|
||||
}
|
||||
}
|
||||
ADFGVX=cipher()
|
||||
for ADFGVX {
|
||||
.SetSpecific "A9GKMF1DQRSBVX8Z0WTEJLOPY5U4CN2H76I3"
|
||||
.SetKey "volcanism"
|
||||
.Display
|
||||
encode=.Encrypt("ATTACKAT1200AM")
|
||||
Print "Encoded: ";encode
|
||||
Print "Decoded: ";.Decrypt(encode)
|
||||
Rem { ' using randomblock
|
||||
thisblock=""
|
||||
.SetRandom &thisblock
|
||||
Print "Random Block:";thisblock
|
||||
.Display
|
||||
encode=.Encrypt("ATTACKAT1200AM")
|
||||
Print "Encoded: ";encode
|
||||
Print "Decoded: ";.Decrypt(encode)
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckADFGVX_Cipher
|
||||
Loading…
Add table
Add a link
Reference in a new issue