def test_password_metrics(self): metrics = passwordmetrics.metrics('correcthorseb!wdbatterystaplerWd3t') self.assertEqual(metrics['words'], {'et', 'stapler', 'i', 'correct', 'battery', 'horse'}) self.assertEqual(metrics['used_groups'], {'uppercase', 'lowercase', 'punctuation', 'digits'}) self.assertEqual(metrics['unused_groups'], {'non-printable', 'whitespace', 'other'}) self.assertEqual(metrics['length'], 34) self.assertAlmostEqual(metrics['entropy'], 101.57032841892621) self.assertAlmostEqual(metrics['word_entropy'], 62.24279530886037) self.assertAlmostEqual(metrics['character_entropy'], 39.32753311006583) metrics = passwordmetrics.metrics('b4naNAf!ddler') self.assertEqual(metrics['words'], {'banana', 'fiddler'}) self.assertEqual(metrics['used_groups'], {'uppercase', 'lowercase', 'punctuation', 'digits'}) self.assertEqual(metrics['unused_groups'], {'non-printable', 'whitespace', 'other'}) self.assertEqual(metrics['length'], 13) self.assertAlmostEqual(metrics['entropy'], 40.37060138599877) self.assertAlmostEqual(metrics['word_entropy'], 29.585966540441248) self.assertAlmostEqual(metrics['character_entropy'], 10.784634845557521) # Repeated words do not increase entropy # (Although they probably should add 1) self.assertEqual(passwordmetrics.metrics('battery')['entropy'], passwordmetrics.metrics('batterybattery')['entropy']) # Repeated substitutions do not increase entropy: self.assertEqual(passwordmetrics.metrics('b4tterybattery')['entropy'], passwordmetrics.metrics('b4tteryb4ttery')['entropy']) # Differenty substitutions *do' not increase entropy: self.assertNotEqual(passwordmetrics.metrics('b4tteryb4ttery')['entropy'], passwordmetrics.metrics('b4ttery84ttery')['entropy'])
def test_substitutions(self): # This long password gets a reasonable score on characters alone self.assertAlmostEqual(passwordmetrics._character_entropy('Tr0ub4dor&3')[0], 65.54588851677637) # But much worse when considering it uses a word, even though it's misspelled and only # appears once in the whole corpus (because I put it there). self.assertAlmostEqual(passwordmetrics.metrics('Tr0ub4dor&3')['entropy'], 42.11714046349914) # Although still better than if there was no substitutions in the word self.assertAlmostEqual(passwordmetrics.metrics('Troubador&3')['entropy'], 31.332505617941614) words, rest = passwordmetrics._find_words('batterybattery', self.words) self.assertEquals(rest, '') words, rest = passwordmetrics._find_words('b4tteryb4ttery', self.words) self.assertEquals(rest, '4') words, rest = passwordmetrics._find_words('b4ttery8attery', self.words) self.assertEquals(rest, '48')
def test_custom_wordlist(self): # You might want to include non-english words in the word list. words = {} # Open a toy wordlist with open('docs/ordlista_sv.txt', 'rt', encoding='latin-1') as wordlist: for line in wordlist.readlines(): word, entropy = line.strip().split(' ') words[word] = float(entropy) passwordmetrics.configure(words=words) # It won't find English words res = passwordmetrics.metrics('correcthorsebatterystapler') self.assertEqual(res['words'], set()) # It will find some Swedish words res = passwordmetrics.metrics('korrekthästbatterihäftapparat') self.assertEqual(res['words'], set([u'batteri', u'korrekt', u'h\xe4ftapparat', u'h\xe4st']))
def test_password_entropy(self): self.assertAlmostEqual(passwordmetrics.metrics('abcdefgh')['entropy'], 36.7646671442273) self.assertAlmostEqual(passwordmetrics.metrics('xyFg98%!')['entropy'], 55.49709479680921) self.assertAlmostEqual(passwordmetrics.metrics('correcthorsebatterystaple')['entropy'], 45.58216824444706)