示例#1
0
        // find lowest Hamming Distance for each possible keysize from MIN_KEYSIZE to MAX_KEYSIZE
        // Note: With minimal samples, you may not get the correct lowest calculated value. (using 1 or 2 for example)
        public static IEnumerable <HammingScore> FindProbableKeySize(byte[] cipherBytes, int minKeySize = 1, int maxKeySize = 40, int numSamples = 6, int topCnt = 3)
        {
            var hamList = new List <HammingScore>();

            if (numSamples < 1)
            {
                throw new ArgumentException("Number of samples must be one or greater");
            }
            int minCipherSizeReq = (numSamples + 1) * maxKeySize;

            if (minCipherSizeReq > cipherBytes.Length)
            {
                throw new ArgumentException($"Cipher bytes must be at least {minCipherSizeReq} bytes to accomodate number of samples.");
            }
            for (int keySize = minKeySize; keySize <= maxKeySize; keySize++)
            {
                uint runTot = 0;
                for (int sampleNum = 0; sampleNum < numSamples; sampleNum++)
                {
                    int startNdx = sampleNum * keySize;
                    runTot += MHString.HammingDistance(cipherBytes, startNdx, startNdx + keySize, keySize);
                }
                double avg = Math.Round(((double)runTot / (double)(keySize * numSamples)), 5);
                hamList.Add(new HammingScore(keySize, numSamples, avg));
            }
            return(hamList.OrderBy(h => h.AvgScore).Take(topCnt).ToList());
        }