source: trunk/CrypPlugins/Transposition/Transposition.cs @ 816

Last change on this file since 816 was 816, checked in by kohnen, 12 years ago
  • minor changes at Transposition
  • added double transposition sample
File size: 30.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.ComponentModel;
6
7using Cryptool;
8using Cryptool.PluginBase.IO;
9using Cryptool.PluginBase;
10using Cryptool.PluginBase.Cryptography;
11using Cryptool.PluginBase.Miscellaneous;
12
13namespace Transposition
14{
15    [Author("Daniel Kohnen, Julian Weyers, Simon Malischewski, Armin Wiefels", "kohnen@cryptool.org, weyers@cryptool.org, malischewski@cryptool.org, wiefels@cryptool.org", "Universität Duisburg-Essen", "http://www.uni-due.de")]
16    [PluginInfo(false, "Transposition", "Transposition cipher", "", "Transposition/Images/icon.png", "Transposition/Images/encrypt.png", "Transposition/Images/decrypt.png")]
17    [EncryptionType(EncryptionType.Classic)]
18    public class Transposition : IEncryption
19    {
20        # region Private variables
21
22        private String keyword = "";
23        private String input = "";
24        private String output = "";
25        private TranspositionSettings settings;
26
27        private char[,] read_in_matrix;
28        private char[,] permuted_matrix;
29        private int[] key;
30        # endregion
31
32        /// <summary>
33        /// Constructor
34        /// </summary>
35        public Transposition()
36        {
37            this.settings = new TranspositionSettings();
38        }
39
40        /// <summary>
41        /// Get or set all settings for this algorithm.
42        /// </summary>
43        public ISettings Settings
44        {
45            get { return this.settings; }
46            set { this.settings = (TranspositionSettings)value; }
47        }
48
49        # region getter methods
50
51        /// <summary>
52        /// Get read in matrix.
53        /// </summary>
54        public char[,] Read_in_matrix
55        {
56            get
57            {
58                return read_in_matrix;
59            }
60        }
61
62        /// <summary>
63        /// Get permuted matrix.
64        /// </summary>
65        public char[,] Permuted_matrix
66        {
67            get
68            {
69                return permuted_matrix;
70            }
71        }
72
73        /// <summary>
74        /// Get numerical key order.
75        /// </summary>
76        public int[] Key
77        {
78            get
79            {
80                return key;
81            }
82        }
83        # endregion
84
85        # region Properties
86
87        [PropertyInfo(Direction.InputData, "Input", "input", "Text to be encrypted.", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
88        public string Input
89        {
90            get
91            {
92                return this.input;
93            }
94
95            set
96            {
97                this.input = value;
98                OnPropertyChange("Input");
99            }
100        }
101
102        [PropertyInfo(Direction.InputData, "Keyword", "keyword", "Keyword used for encryption", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
103        public string Keyword
104        {
105            get
106            {
107                return this.keyword;
108            }
109
110            set
111            {
112                this.keyword = value;
113                OnPropertyChange("Keyword");
114            }
115        }
116
117        [PropertyInfo(Direction.OutputData, "Output", "output", "", DisplayLevel.Beginner)]
118        public string Output
119        {
120            get
121            {
122                return this.output;
123            }
124            set
125            {
126                this.output = value;
127                OnPropertyChange("Output");
128            }
129        }
130
131        private void OnPropertyChange(String propertyname)
132        {
133            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(propertyname));
134        }
135
136        private void ProgressChanged(double value, double max)
137        {
138            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
139        }
140
141        # endregion
142
143        #region IPlugin Member
144
145        public void Dispose()
146        {
147
148        }
149
150        public void Execute()
151        {
152            ProcessTransposition();
153        }
154
155        public void Initialize()
156        {
157
158        }
159
160        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
161
162        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
163
164        public event StatusChangedEventHandler OnPluginStatusChanged;
165
166        public void Pause()
167        {
168
169        }
170
171        public void PostExecution()
172        {
173
174        }
175
176        public void PreExecution()
177        {
178
179        }
180
181        public System.Windows.Controls.UserControl Presentation
182        {
183            get { return null; }
184        }
185
186        public System.Windows.Controls.UserControl QuickWatchPresentation
187        {
188            get { return null; }
189        }
190
191        public void Stop()
192        {
193
194        }
195
196        #endregion
197
198        #region INotifyPropertyChanged Member
199
200        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
201
202        #endregion
203
204        # region Private Methods
205
206        private void ProcessTransposition()
207        {
208            try
209            {
210                if (keyword.Contains(','))
211                {
212                    key = get_Keyword_Array(keyword);
213                }
214
215                else
216                {
217                    key = sortKey(keyword);
218                }
219
220                switch (settings.Action)
221                {
222                    case 0:
223                        Output = encrypt(input, key);
224                        break;
225                    case 1:
226                        Output = decrypt(input, key);
227                        break;
228                    default:
229                        break;
230                }
231                ProgressChanged(1, 1);
232            }
233
234            catch (Exception)
235            {
236                Transposition_LogMessage("Keyword is not valid", NotificationLevel.Error);
237                Output = "";
238            }
239        }
240
241        private String encrypt(String input, int[] key)
242        {
243            if (key != null && input != null && key.Length > 0)
244            {
245                if (is_Valid_Keyword(key))
246                {
247                    String encrypted = "";
248
249                    if (((TranspositionSettings.PermutationMode)settings.Permutation).Equals(TranspositionSettings.PermutationMode.byRow))
250                    {
251                        switch ((TranspositionSettings.ReadInMode)settings.ReadIn)
252                        {
253                            case TranspositionSettings.ReadInMode.byRow:
254                                read_in_matrix = enc_read_in_by_row_if_row_perm(input, key.Length); break;
255                            case TranspositionSettings.ReadInMode.byColumn:
256                                read_in_matrix = enc_read_in_by_column_if_row_perm(input, key.Length); break;
257                            default:
258                                break;
259                        }
260
261                        permuted_matrix = enc_permute_by_row(read_in_matrix, key);
262
263                        switch ((TranspositionSettings.ReadOutMode)settings.ReadOut)
264                        {
265                            case TranspositionSettings.ReadOutMode.byRow:
266                                encrypted = read_out_by_row_if_row_perm(permuted_matrix, key.Length); break;
267                            case TranspositionSettings.ReadOutMode.byColumn:
268                                encrypted = read_out_by_column_if_row_perm(permuted_matrix, key.Length); break;
269                            default:
270                                break;
271                        }
272                    }
273
274                    // permute by column:
275                    else
276                    {
277                        switch ((TranspositionSettings.ReadInMode)settings.ReadIn)
278                        {
279                            case TranspositionSettings.ReadInMode.byRow:
280                                read_in_matrix = enc_read_in_by_row(input, key.Length); break;
281                            case TranspositionSettings.ReadInMode.byColumn:
282                                read_in_matrix = enc_read_in_by_column(input, key.Length); break;
283                            default:
284                                break;
285                        }
286
287                        permuted_matrix = enc_permut_by_column(read_in_matrix, key);
288
289                        switch ((TranspositionSettings.ReadOutMode)settings.ReadOut)
290                        {
291                            case TranspositionSettings.ReadOutMode.byRow:
292                                encrypted = read_out_by_row(permuted_matrix, key.Length); break;
293                            case TranspositionSettings.ReadOutMode.byColumn:
294                                encrypted = read_out_by_column(permuted_matrix, key.Length); break;
295                            default:
296                                break;
297                        }
298                    }
299                    return encrypted;
300                }
301                else
302                {
303                    Transposition_LogMessage("Keyword is not valid", NotificationLevel.Error);
304                    return "";
305                }
306            }
307            else
308            {
309                // 2do: Anzeige "Kein gültiges Keyword
310                return "";
311            }
312        }
313
314        private String decrypt(String input, int[] key)
315        {
316            if (key != null && input != null && key.Length > 0)
317            {
318                if (is_Valid_Keyword(key))
319                {
320                    String decrypted = "";
321                    if (((TranspositionSettings.PermutationMode)settings.Permutation).Equals(TranspositionSettings.PermutationMode.byRow))
322                    {
323                        switch ((TranspositionSettings.ReadOutMode)settings.ReadOut)
324                        {
325                            case TranspositionSettings.ReadOutMode.byRow:
326                                read_in_matrix = dec_read_in_by_row_if_row_perm(input, key); break;
327                            case TranspositionSettings.ReadOutMode.byColumn:
328                                read_in_matrix = dec_read_in_by_column_if_row_perm(input, key); break;
329                            default:
330                                break;
331                        }
332
333                        permuted_matrix = dec_permut_by_row(read_in_matrix, key);
334
335                        switch ((TranspositionSettings.ReadInMode)settings.ReadIn)
336                        {
337                            case TranspositionSettings.ReadInMode.byRow:
338                                decrypted = read_out_by_row_if_row_perm(permuted_matrix, key.Length); break;
339                            case TranspositionSettings.ReadInMode.byColumn:
340                                decrypted = read_out_by_column_if_row_perm(permuted_matrix, key.Length); break;
341                            default:
342                                break;
343                        }
344                    }
345
346                    // permute by column:
347                    else
348                    {
349                        switch ((TranspositionSettings.ReadOutMode)settings.ReadOut)
350                        {
351                            case TranspositionSettings.ReadOutMode.byRow:
352                                read_in_matrix = dec_read_in_by_row(input, key); break;
353                            case TranspositionSettings.ReadOutMode.byColumn:
354                                read_in_matrix = dec_read_in_by_column(input, key); break;
355                            default:
356                                break;
357                        }
358
359                        permuted_matrix = dec_permut_by_column(read_in_matrix, key);
360
361                        switch ((TranspositionSettings.ReadInMode)settings.ReadIn)
362                        {
363                            case TranspositionSettings.ReadInMode.byRow:
364                                decrypted = read_out_by_row(permuted_matrix, key.Length); break;
365                            case TranspositionSettings.ReadInMode.byColumn:
366                                decrypted = read_out_by_column(permuted_matrix, key.Length); break;
367                            default:
368                                break;
369                        }
370                    }
371
372                    return decrypted;
373                }
374                else
375                {
376                    Transposition_LogMessage("Keyword is not valid", NotificationLevel.Error);
377                    return "";
378                }
379            }
380            else
381            {
382                // 2do: Anzeige "Kein gültiges Keyword
383                return "";
384            }
385        }
386
387        private char[,] enc_read_in_by_row(String input, int keyword_length)
388        {
389            int size = input.Length / keyword_length;
390
391            if (input.Length % keyword_length != 0)
392            {
393                size++;
394            }
395
396            int pos = 0;
397            char[,] matrix = new char[keyword_length, size];
398
399            for (int i = 0; i < size; i++)
400            {
401                for (int j = 0; j < keyword_length; j++)
402                {
403                    if (pos < input.Length)
404                    {
405                        matrix[j, i] = input[pos];
406                        pos++;
407                    }
408                }
409            }
410            return matrix;
411        }
412
413        private char[,] enc_read_in_by_column(String input, int keyword_length)
414        {
415            int size = input.Length / keyword_length;
416            int offs = input.Length % keyword_length;
417            if (offs != 0)
418            {
419                size++;
420            }
421
422            int pos = 0;
423
424            char[,] matrix = new char[keyword_length, size];
425            for (int i = 0; i < keyword_length; i++)
426            {
427                for (int j = 0; j < size; j++)
428                {
429                    if (pos < input.Length)
430                    {
431                        if (offs > 0 && j == size - 1 && i >= offs) { }
432                        else
433                        {
434                            matrix[i, j] = input[pos];
435                            pos++;
436                        }
437                    }
438                }
439            }
440            return matrix;
441        }
442
443        private char[,] enc_read_in_by_row_if_row_perm(String input, int keyword_length)
444        {
445            int height = keyword_length;
446            int length = input.Length / keyword_length;
447            int offs = input.Length % keyword_length;
448            if (offs != 0)
449            {
450                length++;
451            }
452
453            char[,] matrix = new char[length, height];
454            int pos = 0;
455
456            for (int i = 0; i < height; i++)
457            {
458                for (int j = 0; j < length; j++)
459                {
460                    if (pos < input.Length)
461                    {
462                        if (j.Equals(length - 1) && offs != 0)
463                        {
464                            if (i < offs)
465                            {
466                                matrix[j, i] = input[pos];
467                                pos++;
468                            }
469                        }
470
471                        else
472                        {
473                            matrix[j, i] = input[pos];
474                            pos++;
475                        }
476                    }
477                }
478            }
479            return matrix;
480        }
481
482        private char[,] enc_read_in_by_column_if_row_perm(String input, int keyword_length)
483        {
484            int height = keyword_length;
485            int length = input.Length / keyword_length;
486            int offs = input.Length % keyword_length;
487            if (offs != 0)
488            {
489                length++;
490            }
491
492            char[,] matrix = new char[length, height];
493            int pos = 0;
494
495            for (int i = 0; i < length; i++)
496            {
497                for (int j = 0; j < height; j++)
498                {
499                    if (pos < input.Length)
500                    {
501                        matrix[i, j] = input[pos];
502                        pos++;
503                    }
504                }
505            }
506            return matrix;
507        }
508
509        private char[,] dec_read_in_by_column(String input, int[] keyword)
510        {
511            int size = input.Length / keyword.Length;
512            int offs = input.Length % keyword.Length;
513            if (offs != 0)
514            {
515                size++;
516            }
517
518            char[,] matrix = new char[keyword.Length, size];
519            int pos = 0;
520
521            for (int i = 0; i < keyword.Length; i++)
522            {
523                for (int j = 0; j < size; j++)
524                {
525                    if (pos < input.Length)
526                    {
527                        if ((!offs.Equals(0)) && j.Equals(size - 1))
528                        {
529                            bool ok = false;
530
531                            for (int k = 0; k < offs; k++)
532                            {
533                                if ((keyword[k] - 1).Equals(i))
534                                {
535                                    ok = true;
536                                }
537                            }
538
539                            if (ok)
540                            {
541                                matrix[i, j] = input[pos];
542                                pos++;
543                            }
544
545                        }
546                        else
547                        {
548                            matrix[i, j] = input[pos];
549                            pos++;
550                        }
551                    }
552                }
553            }
554            return matrix;
555        }
556
557        private char[,] dec_read_in_by_column_if_row_perm(String input, int[] keyword)
558        {
559            int size = input.Length / keyword.Length;
560            int offs = input.Length % keyword.Length;
561            if (offs != 0)
562            {
563                size++;
564            }
565
566            char[,] matrix = new char[size, keyword.Length];
567            int pos = 0;
568
569            for (int i = 0; i < size; i++)
570            {
571                for (int j = 0; j < keyword.Length; j++)
572                {
573                    if (pos < input.Length)
574                    {
575                        if ((!offs.Equals(0)) && i.Equals(size - 1))
576                        {
577                            bool ok = false;
578
579                            for (int k = 0; k < offs; k++)
580                            {
581                                if ((keyword[k] - 1).Equals(j))
582                                {
583                                    ok = true;
584                                }
585                            }
586
587                            if (ok)
588                            {
589                                matrix[i, j] = input[pos];
590                                pos++;
591                            }
592
593                        }
594                        else
595                        {
596                            matrix[i, j] = input[pos];
597                            pos++;
598                        }
599                    }
600                }
601            }
602            return matrix;
603        }
604
605        private char[,] dec_read_in_by_row(String input, int[] keyword)
606        {
607            int size = input.Length / keyword.Length;
608            int offs = input.Length % keyword.Length;
609            if (offs != 0)
610            {
611                size++;
612            }
613
614            char[,] matrix = new char[keyword.Length, size];
615            int pos = 0;
616
617            for (int i = 0; i < size; i++)
618            {
619                for (int j = 0; j < keyword.Length; j++)
620                {
621                    if (pos < input.Length)
622                    {
623                        if ((!offs.Equals(0)) && i.Equals(size - 1))
624                        {
625                            bool ok = false;
626
627                            for (int k = 0; k < offs; k++)
628                            {
629                                if ((keyword[k] - 1).Equals(j))
630                                {
631                                    ok = true;
632                                }
633                            }
634
635                            if (ok)
636                            {
637                                matrix[j, i] = input[pos];
638                                pos++;
639                            }
640
641                        }
642                        else
643                        {
644                            matrix[j, i] = input[pos];
645                            pos++;
646                        }
647                    }
648                }
649            }
650            return matrix;
651        }
652
653        private char[,] dec_read_in_by_row_if_row_perm(String input, int[] keyword)
654        {
655            int size = input.Length / keyword.Length;
656            int offs = input.Length % keyword.Length;
657            if (offs != 0)
658            {
659                size++;
660            }
661
662            char[,] matrix = new char[size, keyword.Length];
663            int pos = 0;
664
665            for (int i = 0; i < keyword.Length; i++)
666            {
667                for (int j = 0; j < size; j++)
668                {
669                    if (pos < input.Length)
670                    {
671                        if ((!offs.Equals(0)) && j.Equals(size - 1))
672                        {
673                            bool ok = false;
674
675                            for (int k = 0; k < offs; k++)
676                            {
677                                if ((keyword[k] - 1).Equals(i))
678                                {
679                                    ok = true;
680                                }
681                            }
682
683                            if (ok)
684                            {
685                                matrix[j, i] = input[pos];
686                                pos++;
687                            }
688
689                        }
690                        else
691                        {
692                            matrix[j, i] = input[pos];
693                            pos++;
694                        }
695                    }
696                }
697            }
698            return matrix;
699        }
700
701        private char[,] enc_permut_by_column(char[,] readin_matrix, int[] keyword)
702        {
703            int x = keyword.Length;
704            int y = readin_matrix.Length / keyword.Length;
705            char[,] matrix = new char[x, y];
706            int pos = 0;
707
708            for (int i = 1; i <= keyword.Length; i++)
709            {
710                for (int j = 0; j < keyword.Length; j++)
711                {
712                    if (i.Equals(keyword[j]))
713                    {
714                        pos = j;
715                    }
716                }
717
718                for (int j = 0; j < y; j++)
719                {
720                    matrix[i - 1, j] = readin_matrix[pos, j];
721                }
722            }
723            return matrix;
724        }
725
726        private char[,] enc_permute_by_row(char[,] readin_matrix, int[] keyword)
727        {
728            int y = keyword.Length;
729            int x = readin_matrix.Length / keyword.Length;
730            char[,] matrix = new char[x, y];
731            int pos = 0;
732
733            for (int i = 1; i <= y; i++)
734            {
735                for (int j = 0; j < keyword.Length; j++)
736                {
737                    if (keyword[j].Equals(i))
738                    {
739                        pos = j;
740                    }
741                }
742
743                for (int j = 0; j < x; j++)
744                {
745                    matrix[j, i - 1] = readin_matrix[j, pos];
746                }
747            }
748            return matrix;
749        }
750
751        private char[,] dec_permut_by_column(char[,] readin_matrix, int[] keyword)
752        {
753            int x = keyword.Length;
754            int y = readin_matrix.Length / keyword.Length;
755            char[,] matrix = new char[x, y];
756
757            for (int i = 0; i < x; i++)
758            {
759                for (int j = 0; j < y; j++)
760                {
761                    matrix[i, j] = readin_matrix[keyword[i] - 1, j];
762                }
763            }
764            return matrix;
765        }
766
767        private static char[,] dec_permut_by_row(char[,] readin_matrix, int[] keyword)
768        {
769            int x = keyword.Length;
770            int y = readin_matrix.Length / keyword.Length;
771            char[,] matrix = new char[y, x];
772
773            for (int i = 0; i < x; i++)
774            {
775                for (int j = 0; j < y; j++)
776                {
777                    matrix[j, i] = readin_matrix[j, keyword[i] - 1];
778                }
779            }
780            return matrix;
781        }
782
783        private String read_out_by_row(char[,] matrix, int keyword_length)
784        {
785            int x = keyword_length;
786            int y = matrix.Length / keyword_length;
787            String enc = "";
788            char empty_char = new char();
789
790            for (int i = 0; i < y; i++)
791            {
792                for (int j = 0; j < x; j++)
793                {
794                    char tmp = matrix[j, i];
795                    if (!tmp.Equals(empty_char))
796                    {
797                        enc += tmp;
798                    }
799                }
800            }
801            return enc;
802        }
803
804        private String read_out_by_row_if_row_perm(char[,] matrix, int keyword_length)
805        {
806            int y = keyword_length;
807            int x = matrix.Length / keyword_length;
808            String enc = "";
809            char empty_char = new char();
810
811            for (int i = 0; i < y; i++)
812            {
813                for (int j = 0; j < x; j++)
814                {
815                    char tmp = matrix[j, i];
816                    if (!tmp.Equals(empty_char))
817                    {
818                        enc += tmp;
819                    }
820                }
821            }
822            return enc;
823        }
824
825        private String read_out_by_column(char[,] matrix, int keyword_length)
826        {
827            int x = keyword_length;
828            int y = matrix.Length / keyword_length;
829            String enc = "";
830            char empty_char = new char();
831
832            for (int i = 0; i < x; i++)
833            {
834                for (int j = 0; j < y; j++)
835                {
836                    char tmp = matrix[i, j];
837                    if (!tmp.Equals(empty_char))
838                    {
839                        enc += tmp;
840                    }
841                }
842            }
843            return enc;
844        }
845
846        private String read_out_by_column_if_row_perm(char[,] matrix, int keyword_length)
847        {
848            int y = keyword_length;
849            int x = matrix.Length / keyword_length;
850            String enc = "";
851            char empty_char = new char();
852
853            for (int i = 0; i < x; i++)
854            {
855                for (int j = 0; j < y; j++)
856                {
857                    char tmp = matrix[i, j];
858                    if (!tmp.Equals(empty_char))
859                    {
860                        enc += tmp;
861                    }
862                }
863            }
864            return enc;
865        }
866
867        private int[] get_Keyword_Array(String keyword)
868        {
869            try
870            {
871                int length = 1;
872                char komma = ',';
873
874                for (int i = 0; i < keyword.Length; i++)
875                {
876                    if (keyword[i].Equals(komma))
877                    {
878                        length++;
879                    }
880                }
881
882                int[] keys = new int[length];
883                String tmp = "";
884                int pos = 0;
885                for (int i = 0; i < keyword.Length; i++)
886                {
887                    if (i.Equals(keyword.Length - 1))
888                    {
889                        tmp += keyword[i];
890                        keys[pos] = Convert.ToInt32(tmp);
891                    }
892
893                    else
894                    {
895                        if (keyword[i].Equals(komma))
896                        {
897                            keys[pos] = Convert.ToInt32(tmp);
898                            tmp = "";
899                            pos++;
900                        }
901                        else
902                        {
903                            tmp += keyword[i];
904                        }
905                    }
906                }
907                return keys;
908            }
909            catch (FormatException)
910            {
911                return null;
912            }
913        }
914
915        private bool is_Valid_Keyword(int[] keyword)
916        {
917            for (int i = 1; i <= keyword.Length; i++)
918            {
919                bool exists = false;
920
921                for (int j = 0; j < keyword.Length; j++)
922                {
923                    if (i.Equals(keyword[j]))
924                    {
925                        exists = true;
926                    }
927                }
928
929                if (!exists)
930                {
931                    return false;
932                }
933            }
934            return true;
935        }
936
937        public int[] sortKey(String input)
938        {
939            if (input != null && !input.Equals(""))
940            {
941                String key = input;
942                Char[] keyChars = key.ToCharArray();
943                Char[] orgChars = key.ToCharArray();
944                int[] rank = new int[keyChars.Length];
945                Array.Sort(keyChars);
946
947                for (int i = 0; i < orgChars.Length; i++)
948                {
949                    rank[i] = (Array.IndexOf(keyChars, orgChars[i])) + 1;
950                    keyChars[Array.IndexOf(keyChars, orgChars[i])] = (char)0;
951                }
952                return rank;
953            }
954            return null;
955        }
956
957        private void Transposition_LogMessage(string msg, NotificationLevel loglevel)
958        {
959            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(msg, this, loglevel));
960        }
961
962        # endregion
963    }
964}
Note: See TracBrowser for help on using the repository browser.