[4sem] isaip01 done
This commit is contained in:
parent
494525d878
commit
6d9a79be20
12 changed files with 410 additions and 0 deletions
8
4sem/isaip/01/PlayfairCypher/.gitignore
vendored
Normal file
8
4sem/isaip/01/PlayfairCypher/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
|
||||||
|
*.user
|
||||||
12
4sem/isaip/01/PlayfairCypher/App.axaml
Normal file
12
4sem/isaip/01/PlayfairCypher/App.axaml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Application xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:PlayfairCypher"
|
||||||
|
x:Class="PlayfairCypher.App">
|
||||||
|
<Application.DataTemplates>
|
||||||
|
<local:ViewLocator/>
|
||||||
|
</Application.DataTemplates>
|
||||||
|
|
||||||
|
<Application.Styles>
|
||||||
|
<FluentTheme Mode="Light"/>
|
||||||
|
</Application.Styles>
|
||||||
|
</Application>
|
||||||
29
4sem/isaip/01/PlayfairCypher/App.axaml.cs
Normal file
29
4sem/isaip/01/PlayfairCypher/App.axaml.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
using PlayfairCypher.ViewModels;
|
||||||
|
using PlayfairCypher.Views;
|
||||||
|
|
||||||
|
namespace PlayfairCypher
|
||||||
|
{
|
||||||
|
public class App : Application
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnFrameworkInitializationCompleted()
|
||||||
|
{
|
||||||
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
|
{
|
||||||
|
desktop.MainWindow = new MainWindow
|
||||||
|
{
|
||||||
|
DataContext = new MainWindowViewModel(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
4sem/isaip/01/PlayfairCypher/Assets/avalonia-logo.ico
Normal file
BIN
4sem/isaip/01/PlayfairCypher/Assets/avalonia-logo.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
161
4sem/isaip/01/PlayfairCypher/Models/PlayfairCrypto.cs
Normal file
161
4sem/isaip/01/PlayfairCypher/Models/PlayfairCrypto.cs
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
// ReSharper disable StringLiteralTypo
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace PlayfairCypher.Models {
|
||||||
|
public class PlayfairCrypto {
|
||||||
|
private static readonly HashSet<char> EnAlphabet = new("ABCDEFGHIKLMNOPQRSTUVWXYZ");
|
||||||
|
|
||||||
|
public string Encrypt(string keyword, string text) {
|
||||||
|
var keyTable = GenerateTable(keyword);
|
||||||
|
var pairs = FormPairs(text);
|
||||||
|
|
||||||
|
var data = new StringBuilder(32);
|
||||||
|
|
||||||
|
foreach (var pair in pairs) {
|
||||||
|
var idx1 = FindCharIndex(ref keyTable, pair[0]);
|
||||||
|
var idx2 = FindCharIndex(ref keyTable, pair[1]);
|
||||||
|
|
||||||
|
var x1 = idx1 / 5; // x for rows
|
||||||
|
var y1 = idx1 % 5; // and y for cols
|
||||||
|
var x2 = idx2 / 5;
|
||||||
|
var y2 = idx2 % 5;
|
||||||
|
|
||||||
|
char c1, c2;
|
||||||
|
if (y1 == y2) {
|
||||||
|
c1 = keyTable[WrapIndex(x1 + 1), y1];
|
||||||
|
c2 = keyTable[WrapIndex(x2 + 1), y1];
|
||||||
|
}
|
||||||
|
else if (x1 == x2) {
|
||||||
|
c1 = keyTable[x1, WrapIndex(y1 + 1)];
|
||||||
|
c2 = keyTable[x1, WrapIndex(y2 + 1)];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c1 = keyTable[x1, y2];
|
||||||
|
c2 = keyTable[x2, y1];
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Append(c1).Append(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Decrypt(string keyword, string text) {
|
||||||
|
var keyTable = GenerateTable(keyword);
|
||||||
|
var pairs = FormPairs(text);
|
||||||
|
|
||||||
|
var data = new StringBuilder(32);
|
||||||
|
|
||||||
|
foreach (var pair in pairs) {
|
||||||
|
var idx1 = FindCharIndex(ref keyTable, pair[0]);
|
||||||
|
var idx2 = FindCharIndex(ref keyTable, pair[1]);
|
||||||
|
|
||||||
|
var x1 = idx1 / 5; // x for rows
|
||||||
|
var y1 = idx1 % 5; // and y for cols
|
||||||
|
var x2 = idx2 / 5;
|
||||||
|
var y2 = idx2 % 5;
|
||||||
|
|
||||||
|
char c1, c2;
|
||||||
|
if (y1 == y2) {
|
||||||
|
c1 = keyTable[WrapIndex(x1 - 1), y1];
|
||||||
|
c2 = keyTable[WrapIndex(x2 - 1), y1];
|
||||||
|
}
|
||||||
|
else if (x1 == x2) {
|
||||||
|
c1 = keyTable[x1, WrapIndex(y1 - 1)];
|
||||||
|
c2 = keyTable[x1, WrapIndex(y2 - 1)];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c1 = keyTable[x1, y2];
|
||||||
|
c2 = keyTable[x2, y1];
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Append(c1).Append(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private char[,] GenerateTable(string keyword) {
|
||||||
|
char[,] table = new char[5,5];
|
||||||
|
|
||||||
|
keyword = ClearKeyword(keyword);
|
||||||
|
for (var i = 0; i < keyword.Length; i++) {
|
||||||
|
table[i / 5,i % 5] = keyword[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
var kwcSet = new HashSet<char>(keyword);
|
||||||
|
var autoAlphabet = EnAlphabet.Except(kwcSet).ToList();
|
||||||
|
for (var i = keyword.Length; i < 25; i++) {
|
||||||
|
table[i / 5,i % 5] = autoAlphabet[i-keyword.Length];
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ClearKeyword(string keyword) {
|
||||||
|
string data = "";
|
||||||
|
|
||||||
|
keyword = keyword.Replace("J", "I");
|
||||||
|
foreach (var kwc in keyword) {
|
||||||
|
if (!EnAlphabet.Contains(kwc) || kwc == ' ' || data.Contains(kwc)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
data += kwc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindCharIndex(ref char[,] table, char c) {
|
||||||
|
for (var i = 0; i < 25; i++) {
|
||||||
|
if (table[i / 5, i % 5] == c) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentOutOfRangeException($"Character '{c}' not fount in table");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<string> FormPairs(string text) {
|
||||||
|
List<string> data = new ();
|
||||||
|
|
||||||
|
text = text.Replace("J", "I");
|
||||||
|
var cc = text[0];
|
||||||
|
for (var i = 1; i < text.Length; i++) {
|
||||||
|
if (cc != '\0' && !EnAlphabet.Contains(cc)) {
|
||||||
|
cc = '\0';
|
||||||
|
}
|
||||||
|
if (cc == '\0') {
|
||||||
|
cc = text[i];
|
||||||
|
}
|
||||||
|
else if (cc == text[i]) {
|
||||||
|
data.Add("" + cc + "X");
|
||||||
|
cc = text[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.Add("" + cc + text[i]);
|
||||||
|
cc = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cc != '\0') {
|
||||||
|
data.Add("" + cc + "X");
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int WrapIndex(int idx) {
|
||||||
|
if (idx < 0) {
|
||||||
|
idx += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return idx % 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
4sem/isaip/01/PlayfairCypher/PlayfairCypher.csproj
Normal file
17
4sem/isaip/01/PlayfairCypher/PlayfairCypher.csproj
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Models\" />
|
||||||
|
<AvaloniaResource Include="Assets\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Avalonia" Version="0.10.0" />
|
||||||
|
<PackageReference Include="Avalonia.Desktop" Version="0.10.0" />
|
||||||
|
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.0" />
|
||||||
|
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
16
4sem/isaip/01/PlayfairCypher/PlayfairCypher.sln
Normal file
16
4sem/isaip/01/PlayfairCypher/PlayfairCypher.sln
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlayfairCypher", "PlayfairCypher.csproj", "{5AAEBCD9-0ADD-4C76-B1B4-92569D82970B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{5AAEBCD9-0ADD-4C76-B1B4-92569D82970B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5AAEBCD9-0ADD-4C76-B1B4-92569D82970B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5AAEBCD9-0ADD-4C76-B1B4-92569D82970B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5AAEBCD9-0ADD-4C76-B1B4-92569D82970B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
14
4sem/isaip/01/PlayfairCypher/Program.cs
Normal file
14
4sem/isaip/01/PlayfairCypher/Program.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
|
|
||||||
|
namespace PlayfairCypher {
|
||||||
|
internal static class Program {
|
||||||
|
public static void Main(string[] args) {
|
||||||
|
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AppBuilder BuildAvaloniaApp() {
|
||||||
|
return AppBuilder.Configure<App>().UsePlatformDetect().LogToTrace().UseReactiveUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
4sem/isaip/01/PlayfairCypher/ViewLocator.cs
Normal file
33
4sem/isaip/01/PlayfairCypher/ViewLocator.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Templates;
|
||||||
|
using PlayfairCypher.ViewModels;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace PlayfairCypher
|
||||||
|
{
|
||||||
|
public class ViewLocator : IDataTemplate
|
||||||
|
{
|
||||||
|
public bool SupportsRecycling => false;
|
||||||
|
|
||||||
|
public IControl Build(object data)
|
||||||
|
{
|
||||||
|
var name = data.GetType().FullName!.Replace("ViewModel", "View");
|
||||||
|
var type = Type.GetType(name);
|
||||||
|
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
return (Control) Activator.CreateInstance(type)!;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new TextBlock {Text = "Not Found: " + name};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Match(object data)
|
||||||
|
{
|
||||||
|
return data is ReactiveObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reactive.Disposables;
|
||||||
|
using System.Text;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using PlayfairCypher.Models;
|
||||||
|
using ReactiveUI;
|
||||||
|
|
||||||
|
namespace PlayfairCypher.ViewModels {
|
||||||
|
public class MainWindowViewModel : ReactiveObject {
|
||||||
|
private string _keyword = "";
|
||||||
|
private string _inputText = "";
|
||||||
|
private string _outputText = "";
|
||||||
|
private bool _isEncrypting = true;
|
||||||
|
|
||||||
|
private readonly PlayfairCrypto _cryptor;
|
||||||
|
|
||||||
|
public MainWindowViewModel() {
|
||||||
|
_cryptor = new PlayfairCrypto();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Keyword {
|
||||||
|
get => _keyword;
|
||||||
|
set {
|
||||||
|
this.RaiseAndSetIfChanged(ref _keyword, value.ToUpper());
|
||||||
|
CalculateCypher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string InputText {
|
||||||
|
get => _inputText;
|
||||||
|
set {
|
||||||
|
this.RaiseAndSetIfChanged(ref _inputText, value.ToUpper());
|
||||||
|
CalculateCypher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string OutputText {
|
||||||
|
get => _outputText;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _outputText, value.ToUpper());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEncrypting {
|
||||||
|
get => _isEncrypting;
|
||||||
|
set {
|
||||||
|
this.RaiseAndSetIfChanged(ref _isEncrypting, value);
|
||||||
|
InputText = OutputText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearForm() {
|
||||||
|
InputText = "";
|
||||||
|
Keyword = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalculateCypher() {
|
||||||
|
if (InputText.Length == 0) {
|
||||||
|
OutputText = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Keyword.Length == 0) {
|
||||||
|
OutputText = "Error: Keyword is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputText = IsEncrypting? _cryptor.Encrypt(Keyword.Trim(), InputText.Trim()) : _cryptor.Decrypt(Keyword.Trim(), InputText.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
4sem/isaip/01/PlayfairCypher/Views/MainWindow.axaml
Normal file
33
4sem/isaip/01/PlayfairCypher/Views/MainWindow.axaml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:vm="using:PlayfairCypher.ViewModels"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
|
Width="700" Height="300"
|
||||||
|
x:Class="PlayfairCypher.Views.MainWindow"
|
||||||
|
Icon="/Assets/avalonia-logo.ico"
|
||||||
|
Title="PlayfairCypher">
|
||||||
|
|
||||||
|
<Design.DataContext>
|
||||||
|
<vm:MainWindowViewModel/>
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
|
<Grid RowDefinitions="Auto,20,*" Margin="20">
|
||||||
|
<Grid Grid.Row="0" ColumnDefinitions="*,40,Auto,Auto,Auto">
|
||||||
|
<TextBox Grid.Column="0" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Auto" Watermark="Keyword" NewLine=""
|
||||||
|
Text="{Binding Keyword}"/>
|
||||||
|
<CheckBox Grid.Column="2" Content="Encrypting" IsChecked="{Binding IsEncrypting}" />
|
||||||
|
<Button Grid.Column="4" Content="Clear form" Command="{Binding ClearForm}" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="2" ColumnDefinitions="*,Auto,*">
|
||||||
|
<TextBox Grid.Column="0" AcceptsReturn="True" ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
|
Watermark="INPUT" UseFloatingWatermark="True" TextWrapping="Wrap"
|
||||||
|
Text="{Binding InputText}"/>
|
||||||
|
<GridSplitter Grid.Column="1" />
|
||||||
|
<TextBox Grid.Column="2" ScrollViewer.VerticalScrollBarVisibility="Auto" IsReadOnly="True"
|
||||||
|
Watermark="OUTPUT" UseFloatingWatermark="True" TextWrapping="Wrap"
|
||||||
|
Text="{Binding OutputText}"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
18
4sem/isaip/01/PlayfairCypher/Views/MainWindow.axaml.cs
Normal file
18
4sem/isaip/01/PlayfairCypher/Views/MainWindow.axaml.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace PlayfairCypher.Views {
|
||||||
|
public class MainWindow : Window {
|
||||||
|
public MainWindow() {
|
||||||
|
InitializeComponent();
|
||||||
|
#if DEBUG
|
||||||
|
this.AttachDevTools();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent() {
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue