source: trunk/CrypPlugins/Nihilist/Nihilist.cs @ 2334

Last change on this file since 2334 was 2334, checked in by Matthäus Wander, 11 years ago

removed 1006 occurences of DisplayLevel in 218 files (see #122)

File size: 8.7 KB
Line 
1/*                             
2   Copyright 2009-2010 Fabian Enkler, Matthäus Wander
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17
18using System.Collections.Generic;
19using System.ComponentModel;
20using System.Text;
21using System.Windows.Controls;
22using Cryptool.PluginBase;
23using Cryptool.PluginBase.Cryptography;
24using System.Windows;
25using System.Diagnostics;
26using Cryptool.PluginBase.Miscellaneous;
27
28namespace Nihilist
29{
30    [Author("Fabian Enkler", "enkler@cryptool.org", "", "")]
31    [PluginInfo(false, "Nihilist", "Nihilist -- classic digraph polyalphabetic substitution cipher substituting each letter by a 2-digit-number", "", "Nihilist/icon.png")]
32    [EncryptionType(EncryptionType.Classic)]
33    public class Nihilist : IEncryption
34    {
35        public const string ALPHABET = "abcdefghiklmnopqrstuvwxyz";
36
37        private readonly NihilistSettings settings = new NihilistSettings();
38
39        public event PropertyChangedEventHandler PropertyChanged;
40#pragma warning disable 67
41        public event StatusChangedEventHandler OnPluginStatusChanged;
42#pragma warning restore
43        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
44        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
45
46        public ISettings Settings
47        {
48            get { return settings; }
49        }
50
51        public UserControl Presentation
52        {
53            get { return null; }
54        }
55
56        public UserControl QuickWatchPresentation
57        {
58            get { return null; }
59        }
60
61        private byte[] input = new byte[] { };
62        [PropertyInfo(Direction.InputData, "Input byte array", "This is the byte array to be processed by Nihilist cipher.", "", true, false, QuickWatchFormat.Text, null)]
63        public byte[] Input
64        {
65            get { return input; }
66            set
67            {
68                input = value;
69                OnPropertyChanged("Input");
70            }
71        }
72
73        private byte[] output = new byte[] { };
74        [PropertyInfo(Direction.OutputData, "Output byte array", "This is the byte array processed by Nihilist cipher", "", true, false, QuickWatchFormat.Text, null)]
75        public byte[] Output
76        {
77            get { return output; }
78            set
79            {
80                output = value;
81                OnPropertyChanged("Output");
82            }
83        }
84
85        public void PreExecution()
86        {
87
88        }
89
90        // Convert byte[] indexes (0..4, 0..4) to two-digit number (11..55)
91        // 0, 0 -> 11
92        // 4, 1 -> 52
93        private byte ConvertIndexesToTwoDigit(byte[] arr)
94        {
95            Debug.Assert(arr.Length == 2);
96            return ConvertToDimensionOne(arr[0], arr[1]);
97        }
98
99        private byte ConvertToDimensionOne(byte x, byte y)
100        {
101            Debug.Assert(0 <= x && x <= 4);
102            Debug.Assert(0 <= y && y <= 4);
103
104            x++;
105            y++;
106            return (byte) (x * 10 + y);
107        }
108
109        // Convert two-digit number (11..55) to byte[] indexes (0..4, 0..4)
110        // 11 -> 0, 0
111        // 52 -> 4, 1
112        private byte[] ConvertTwoDigitToIndexes(byte z)
113        {
114            Debug.Assert(11 <= z && z <= 55, "Expected 11..55, got: " + z);
115
116            byte x = (byte)(z / 10);
117            byte y = (byte)(z % 10);
118            x--;
119            y--;
120
121            return new byte[] { x, y };
122        }
123
124        public void Execute()
125        {
126            char[,] KeyArray;
127            Dictionary<char, byte[]> CryptMatrix = CreateCryptMatrix(out KeyArray);
128
129            string secondKeyWord = settings.SecondKeyWord.ToLower();
130            byte[] secondKeyNumbers = new byte[secondKeyWord.Length];
131            for(int i = 0; i < secondKeyWord.Length; i++)
132            {
133                char c = secondKeyWord[i];
134                secondKeyNumbers[i] = ConvertIndexesToTwoDigit(CryptMatrix[c]);
135            }
136            if (settings.Action == 0)
137            {
138                string rawInputString = ByteArrayToString(input).ToLower();
139                string inputString = StringUtil.StripUnknownSymbols(ALPHABET, rawInputString);
140                byte[] outputBytes = new byte[inputString.Length];
141                for (int i = 0; i < inputString.Length; i++)
142                {
143                    // convert character -> two-digit number
144                    char plainChar = inputString[i];
145                    byte plainNumber = ConvertIndexesToTwoDigit(CryptMatrix[plainChar]);
146
147                    // calculate cipher number
148                    outputBytes[i] = (byte)(plainNumber + secondKeyNumbers[i % secondKeyNumbers.Length]);
149
150                    OnProgressChanged(i+1, inputString.Length);
151                }
152                this.output = outputBytes;
153            }
154            else
155            {
156                char[] outputChars = new char[input.Length];
157                for (int i = 0; i < input.Length; i++)
158                {
159                    // calculate plain number
160                    byte plainNumber = (byte)(input[i] - secondKeyNumbers[i % secondKeyNumbers.Length]);
161                    if (plainNumber < 11 || plainNumber > 55)
162                    {
163                        GuiLogMessage("Plaintext two-digit-number out of range, expected 11 <= x <= 55, got: " + plainNumber + ". Wrong key?", NotificationLevel.Error);
164                        break;
165                    }
166                    byte[] indexes = ConvertTwoDigitToIndexes(plainNumber);
167
168                    // convert two-digit number -> character
169                    outputChars[i] = KeyArray[indexes[0], indexes[1]];
170
171                    OnProgressChanged(i+1, input.Length);
172                }
173                this.output = CharArrayToByteArray(outputChars);
174            }
175            OnPropertyChanged("Output");
176        }
177
178        private static string ByteArrayToString(byte[] arr)
179        {
180            return Encoding.Default.GetString(arr);
181        }
182
183        private static byte[] CharArrayToByteArray(char[] arr)
184        {
185            return Encoding.Default.GetBytes(arr);
186        }
187
188        private Dictionary<char, byte[]> CreateCryptMatrix(out char[,] KeyArr)
189        {
190            var KeyArray = new char[5, 5];
191            var CharDic = new HashSet<char>();
192            int Row = 0;
193            int Col = 0;
194            foreach (var c in settings.KeyWord.ToLower() + ALPHABET)
195            {
196                if (!CharDic.Contains(c))
197                {
198                    if (Row < KeyArray.GetLength(1))
199                        KeyArray[Row, Col] = c;
200                    CharDic.Add(c);
201                    Col++;
202                    if (Col >= KeyArray.GetLength(0))
203                    {
204                        Col = 0;
205                        Row++;
206                    }
207                }
208            }
209            KeyArr = KeyArray;
210            var CharPosDic = new Dictionary<char, byte[]>();
211            for (byte i = 0; i < KeyArray.GetLength(0); i++)
212            {
213                for (byte j = 0; j < KeyArray.GetLength(1); j++)
214                {
215                    CharPosDic.Add(KeyArray[i, j], new byte[] { i, j });
216                }
217            }
218            return CharPosDic;
219        }
220
221        public void PostExecution()
222        {
223
224        }
225
226        public void Pause()
227        {
228
229        }
230
231        public void Stop()
232        {
233
234        }
235
236        public void Initialize()
237        {
238
239        }
240
241        public void Dispose()
242        {
243
244        }
245
246        private void OnPropertyChanged(string name)
247        {
248            if (PropertyChanged != null)
249                PropertyChanged(this, new PropertyChangedEventArgs(name));
250        }
251
252        private void OnProgressChanged(int value, int max)
253        {
254            if (OnPluginProgressChanged != null)
255                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
256        }
257
258        private void GuiLogMessage(string message, NotificationLevel logLevel)
259        {
260            if (OnGuiLogNotificationOccured != null)
261                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, logLevel));
262        }
263    }
264}
Note: See TracBrowser for help on using the repository browser.