[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