public void TwentyObservations() { BinomialSketch sketch = new BinomialSketch(1024*1024*1024, 64, "Louis Tully as played by Rick Moranis"); string somethingToObserve = "Gosh. It's a nice day out, isn't it?"; int observationCount = sketch.GetNumberOfIndexesSet(somethingToObserve); for (int i = 0; i < 20; i++) { int lastCount = sketch.Observe(somethingToObserve); Assert.Equal(observationCount, lastCount); observationCount++; } Assert.Equal(observationCount, sketch.GetNumberOfIndexesSet(somethingToObserve)); double pNullHypothesis = sketch.TestNullHypothesisThatAllIndexesWereSetByChance(observationCount); Assert.True(pNullHypothesis < 0.01); int minObservationsAtOnePercentConfidence = sketch.CountObservationsForGivenConfidence(observationCount, 0.01d); Assert.True(minObservationsAtOnePercentConfidence > 5); }
public PasswordPopularityTracker( string keyToPreventAlgorithmicComplexityAttacks, long estimatedNumberOfAccounts = DefaultEstimatedNumberOfAccounts, int thresholdRequiredToTrackPreciseOccurrences = DefaultMinCountRequiredToTrackPreciseOccurrences, uint thresholdRequiredToStorePlaintext = DefaultMinCountRequiredToStorePlaintext, double minPercentRequiredToStorePlaintext = DefaultMinPercentRequiredToStorePlaintext) { int numberOfHistoricalPeriods = DefaultNumberOfHistoricalPeriods; uint factorOfGrowthBetweenHistoricalPeriods = DefaultFactorOfGrowthBetweenHistoricalPeriods; LengthOfHistoricalPeriods = new uint[numberOfHistoricalPeriods]; PasswordFrequencyEstimatesForDifferentPeriods = new List<FrequencyTracker<string>>(DefaultNumberOfHistoricalPeriods); uint currentPeriodLength = DefaultLengthOfShortestHistoricalPeriod; for (int period = 0; period < DefaultNumberOfHistoricalPeriods; period++) { LengthOfHistoricalPeriods[period] = currentPeriodLength; PasswordFrequencyEstimatesForDifferentPeriods.Add( new FrequencyTracker<string>((int) currentPeriodLength)); currentPeriodLength *= factorOfGrowthBetweenHistoricalPeriods; } // Reverese the frequency trackers so that the one that tracks the most items is first on the list. PasswordFrequencyEstimatesForDifferentPeriods.Reverse(); long conservativelyHighEstimateOfRowsNeeded = 4 * estimatedNumberOfAccounts / LowEndEstimateOfLoginsBetweenBenignUsersEnteringWrongPasswordRepeatedly; _minCountRequiredToTrackPreciseOccurrences = thresholdRequiredToTrackPreciseOccurrences; _minPercentRequiredToStorePlaintext = minPercentRequiredToStorePlaintext; _minCountRequiredToStorePlaintext = thresholdRequiredToStorePlaintext; // _minPercentRequiredToTrackPreciseOccurrences = minPercentRequiredToTrackPreciseOccurrences; FailedPasswordsRecordedSoFar = 0d; SketchForTestingIfNonexistentAccountIpPasswordHasBeenSeenBefore = new AgingMembershipSketch(DefaultNumberOfSketchColumns, conservativelyHighEstimateOfRowsNeeded); BinomialSketchOfFailedPasswords = new BinomialSketch(SizeOfBinomialLadder, HeightOfBinomialLadder, keyToPreventAlgorithmicComplexityAttacks); // FIXME configuration parameters MapOfHighlyPopularUnsaltedHashedPasswordsToPlaintextPasswords = new Dictionary<string, string>(); }