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}");
|
||||
Loading…
Add table
Add a link
Reference in a new issue