private static bool EvalAddPopularPasswordPattern(List <QePatternInstance>[] vPatterns, char[] vPassword, int i, char[] vSub, double dblCostPerMod) { ulong uDictSize; if (!PopularPasswords.IsPopularPassword(vSub, out uDictSize)) { return(false); } int n = vSub.Length; int d = HammingDist(vSub, 0, vPassword, i, n); double dblCost = Log2((double)uDictSize); // dblCost += log2(n binom d) int k = Math.Min(d, n - d); for (int j = n; j > (n - k); --j) { dblCost += Log2(j); } for (int j = k; j >= 2; --j) { dblCost -= Log2(j); } dblCost += dblCostPerMod * (double)d; vPatterns[i].Add(new QePatternInstance(i, n, PatternID.Dictionary, dblCost)); return(true); }
private static void FindPopularPasswords(char[] vPassword, List <QePatternInstance>[] vPatterns) { int n = vPassword.Length; char[] vLower = new char[n]; char[] vLeet = new char[n]; for (int i = 0; i < n; ++i) { char ch = vPassword[i]; vLower[i] = char.ToLower(ch); vLeet[i] = char.ToLower(DecodeLeetChar(ch)); } char chErased = default(char); Debug.Assert(chErased == char.MinValue); int nMaxLen = Math.Min(n, PopularPasswords.MaxLength); for (int nSubLen = nMaxLen; nSubLen >= 3; --nSubLen) { if (!PopularPasswords.ContainsLength(nSubLen)) { continue; } char[] vSub = new char[nSubLen]; for (int i = 0; i <= (n - nSubLen); ++i) { if (Array.IndexOf <char>(vLower, chErased, i, nSubLen) >= 0) { continue; } Array.Copy(vLower, i, vSub, 0, nSubLen); if (!EvalAddPopularPasswordPattern(vPatterns, vPassword, i, vSub, 0.0)) { Array.Copy(vLeet, i, vSub, 0, nSubLen); if (EvalAddPopularPasswordPattern(vPatterns, vPassword, i, vSub, 1.5)) { Array.Clear(vLower, i, nSubLen); // Not vLeet Debug.Assert(vLower[i] == chErased); } } else { Array.Clear(vLower, i, nSubLen); Debug.Assert(vLower[i] == chErased); } } } }