source: trunk/CrypPlugins/KeySearcher/KeyPattern/Wildcard.cs @ 6085

Last change on this file since 6085 was 6085, checked in by Sven Rech, 7 years ago

KeySearcher key pattern mechanism: allowing input of a wildcard range (like "0-F") that gets interpreted with respect to its underlying pattern.

File size: 7.8 KB
Line 
1/*                             
2   Copyright 2009 Sven Rech (svenrech at googlemail dot com), Uni Duisburg-Essen
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
17using System;
18namespace KeySearcher.KeyPattern
19{
20    internal class Wildcard
21    {
22        private char[] values = new char[256];
23        private int length;
24        private int counter;
25        public bool isSplit
26        {
27            get;
28            private set;
29        }
30
31        public Wildcard(string valuePattern, Wildcard referenceWildcard = null)
32        {
33            isSplit = false;
34            counter = 0;
35            if (valuePattern.Length == 1)
36            {
37                length = 1;
38                values[0] = valuePattern[0];
39            }
40            else
41            {
42                length = 0;
43                int i = 1;
44                while (valuePattern[i] != ']')
45                {
46                    if (valuePattern[i + 1] == '-')
47                    {
48                        var startChar = valuePattern[i];
49                        var endChar = valuePattern[i + 2];
50                        if (startChar > endChar)
51                        {
52                            throw new Exception("Invalid wildcard format!");
53                        }
54
55                        if (referenceWildcard != null)
56                        {
57                            TakeWildcardRangeFromReference(referenceWildcard, startChar, endChar);
58                        }
59                        else
60                        {
61                            for (char c = startChar; c <= endChar; c++)
62                            {
63                                values[length++] = c;
64                            }
65                        }
66
67                        i += 2;
68                    }
69                    else
70                    {
71                        values[length++] = valuePattern[i];
72                    }
73                    i++;
74                }
75            }
76
77            Array.Sort(values, 0, length);
78        }
79
80        private void TakeWildcardRangeFromReference(Wildcard referenceWildcard, char startChar, char endChar)
81        {
82            bool startFound = false;
83            bool endFound = false;
84            for (int ri = 0; ri < referenceWildcard.length; ri++)
85            {
86                var currentRC = referenceWildcard.values[ri];
87                if (!startFound && currentRC == startChar)
88                {
89                    startFound = true;
90                }
91                if (startFound && !endFound)
92                {
93                    values[length++] = currentRC;
94                }
95                if (currentRC == endChar)
96                {
97                    endFound = true;
98                    break;
99                }
100            }
101
102            if (!startFound || !endFound)
103            {
104                throw new Exception("Invalid wildcard format with respect to reference wildcard!");
105            }
106        }
107
108        public Wildcard(Wildcard wc)
109        {
110            isSplit = wc.isSplit;
111            length = wc.length;
112            counter = wc.counter;
113            for (int i = 0; i < 256; i++)
114                values[i] = wc.values[i];
115        }
116
117        public Wildcard(char[] values, int length)
118        {
119            isSplit = false;
120            this.length = length;
121            this.values = values;
122            this.counter = 0;
123        }
124
125        private Wildcard()
126        {
127        }
128
129        public Wildcard[] split()
130        {
131            if (length <= 1)
132                return null;
133            int length1 = this.length - this.counter;
134            Wildcard[] wcs = new Wildcard[2];
135            wcs[0] = new Wildcard();
136            wcs[0].counter = 0;
137            wcs[0].length = length1 / 2;
138            wcs[1] = new Wildcard();
139            wcs[1].counter = 0;
140            wcs[1].length = length1 - wcs[0].length;
141            for (int i = 0; i < wcs[0].length; i++)
142                wcs[0].values[i] = values[this.counter + i];
143            for (int i = 0; i < wcs[1].length; i++)
144                wcs[1].values[i] = values[i + this.counter + wcs[0].length];
145            wcs[0].isSplit = true;
146            wcs[1].isSplit = true;
147            return wcs;
148        }
149
150        public char getChar()
151        {
152            return values[counter];
153        }
154
155        public char getChar(int add)
156        {
157            return values[(counter + add) % length];
158        }
159
160        public bool succ()
161        {
162            counter++;
163            if (counter >= length)
164            {
165                counter = 0;
166                return true;
167            }
168            return false;
169        }
170
171        /// <summary>
172        /// Adds "add" to the counter and returns the carry.
173        /// </summary>
174        /// <param name="add">The carry</param>
175        /// <returns></returns>
176        public int add(int add)
177        {
178            counter += add;
179            if (counter >= length)
180            {
181                int result = counter / length;
182                counter %= length;
183                return result;
184            }
185            return 0;
186        }
187
188        public int size()
189        {
190            return length;
191        }
192
193        public int count()
194        {
195            return counter;
196        }
197
198        public void resetCounter()
199        {
200            counter = 0;
201        }
202
203        public string getRepresentationString()
204        {
205            if (length == 1)
206                return "" + values[0];
207            string res = "[";
208            int begin = 0;
209            for (int i = 1; i < length; i++)
210            {
211                if (values[i - 1] != values[i] - 1)
212                {
213                    if (begin == i - 1)
214                        res += values[begin];
215                    else
216                    {
217                        if (i - 1 - begin == 1)
218                            res += values[begin] + "" + values[i - 1];
219                        else
220                            res += values[begin] + "-" + values[i - 1];
221                    }
222                    begin = i;
223                }
224            }
225            if (begin == length - 1)
226                res += values[begin];
227            else
228            {
229                if (length - 1 - begin == 1)
230                    res += values[begin] + "" + values[length - 1];
231                else
232                    res += values[begin] + "-" + values[length - 1];
233            }
234
235            res += "]";
236            return res;
237        }
238
239        public bool contains(Wildcard wc)
240        {
241            if (wc == null)
242                return false;
243            for (int i = 0; i < wc.length; i++)
244            {
245                bool contains = false;
246                for (int j = 0; j < this.length; j++)
247                {
248                    if (this.values[j] == wc.values[i])
249                    {
250                        contains = true;
251                        break;
252                    }
253                }
254                if (!contains)
255                    return false;
256            }
257            return true;
258        }
259
260        internal int getLength()
261        {
262            return length;
263        }
264
265        internal char[] getChars()
266        {
267            return values;
268        }
269    }
270}
Note: See TracBrowser for help on using the repository browser.