public CipherDictionary MostLikely()
        {
            var ret = new CipherDictionary(this.Count);

            foreach (CipherPossibilities poss in this)
            {
                CipherPair ml = poss.MostLikely();
                if (ml != null)
                {
                    ret.Add(ml);
                }
            }
            return(ret);
        }
        public static ulong[] CalcPairFreqs(int[] data, int[] codelist, CipherPair eof = null)
        {
            //convert the data into a string, so we can use regex on it
            char[] ctext = new char[data.Length * 4];
            Buffer.BlockCopy(data, 0, ctext, 0, data.Length * 4);
            string text = new string(ctext);

            var count = new SortedList <int, ulong>(codelist.Length * codelist.Length, new DuplicateKeyComparer <int>());

            for (int i = 0; i < codelist.Length; i++)
            {
                for (int j = 0; j < codelist.Length; j++)
                {
                    count.Add(Regex.Matches(text, string.Concat(codelist[i], codelist[j])).Count, ((ulong)i << 32) | (uint)j);
                }
            }
            return(count.Select(p => p.Value).ToArray());
        }
        public static int[] CalcSingleFreqs(int[] data, CipherPair eof = null)
        {
            Dictionary <int, int> freqs = new Dictionary <int, int>();

            foreach (int point in data)
            {
                if (eof != null && point == eof.Code)
                {
                    break;
                }
                int freq;
                if (freqs.TryGetValue(point, out freq))
                {
                    freqs[point]++;
                }
                else
                {
                    freqs.Add(point, 1);
                }
            }
            return(freqs.OrderByDescending(pair => pair.Value).Select(pair => pair.Key).ToArray());
        }
示例#4
0
        public void BestGuess()
        {
            CipherPair eof = null;

            if (data[data.Length - 1] == data[data.Length - 2] && data[data.Length - 1] == data[data.Length - 3])
            {
                eof = new CipherPair(data[data.Length - 1], (char)26);
            }

            var codelist = data.Distinct();
            var dicts    = new List <CipherPredictionDictionary>();

            dicts.Add(CipherPredictionDictionary.SingleFrequencyPrediction(data, eof));
            int spaceCode = dicts[0].Find(p => p.MostLikely().Value == ' ').MostLikely().Code;

            dicts.Add(CipherPredictionDictionary.PairFrequencyPrediction(data, codelist, eof));
            dicts.Add(CipherPredictionDictionary.FirstLetterPrediction(data, spaceCode));
            dicts.Add(CipherPredictionDictionary.KnownWordPrediction(data, "<untranslatable>"));
            preDict = CipherPredictionDictionary.AggregateProbabilities(dicts, codelist);
            dict    = preDict.MostLikely();
            dict.AddMissingValues(codelist);
            charsetView.DataSource = dict.BindingList;
        }
示例#5
0
 /// <summary>
 /// Initializes a new instance of <see cref="CipherPossibilities"/> with a code and one possibility specified by a <see cref="CipherPair"/>
 /// </summary>
 public CipherPossibilities(CipherPair pair, double probability) : this(pair.Code)
 {
     Probabilites.Add(pair.Value, probability);
 }
        public static CipherPredictionDictionary SingleFrequencyPrediction(int[] data, CipherPair eof = null)
        {
            const double PROBABILITY_COEFFICIENT = 0.2;
            const int    PRED_DISTANCE           = 4;

            int[] freqs = CalcSingleFreqs(data, eof);
            var   dict  = new CipherPredictionDictionary(freqs.Length + 1);

            for (int i = 0; i < freqs.Length; i++)
            {
                CipherPossibilities poss = dict.Add(freqs[i]);
                //loop over indexes from (i - PRED_DISTANCE) to (i + PRED_DISTANCE), within the bounds of the array
                for (int j = Math.Max(i - PRED_DISTANCE, 0); j < Math.Min(i + PRED_DISTANCE + 1, singleFreqOrder.Length); j++)
                {
                    poss.Add(singleFreqOrder[j], (PRED_DISTANCE - Math.Abs(i - j)) / (double)PRED_DISTANCE * PROBABILITY_COEFFICIENT);
                }
            }
            dict.Insert(dict.Count, new CipherPossibilities(eof, 1.0));

            return(dict);
        }
        public static CipherPredictionDictionary PairFrequencyPrediction(int[] data, IEnumerable <int> codelist, CipherPair eof = null)
        {
            const double PROBABILITY_COEFFICIENT = 0.3;
            const int    PRED_DISTANCE           = 6;

            ulong[] freqs = CalcPairFreqs(data, codelist.ToArray(), eof);
            var     dict  = new CipherPredictionDictionary(freqs.Length + 1);

            for (int i = 0; i < freqs.Length; i++)
            {
                CipherPossibilities poss1 = dict.Add((int)(freqs[i] >> 32));           //first char
                CipherPossibilities poss2 = dict.Add((int)(freqs[i] & uint.MaxValue)); //second char
                //loop over indexes from (i - PRED_DISTANCE) to (i + PRED_DISTANCE), within the bounds of the array
                for (int j = Math.Max(i - PRED_DISTANCE, 0); j < Math.Min(i + PRED_DISTANCE + 1, pairFreqOrder.Length); j++)
                {
                    double prob = (PRED_DISTANCE - Math.Abs(i - j)) / (double)PRED_DISTANCE * PROBABILITY_COEFFICIENT;
                    poss1.Assimilate(pairFreqOrder[j][0], prob);
                    poss2.Assimilate(pairFreqOrder[j][1], prob);
                }
            }
            return(dict);
        }
示例#8
0
 public bool EncodingEquals(CipherPair other)
 {
     return(other != null && other.Code == this.Code && other.Value == this.Value);
 }