Description
The python code produces very different (and worrisome) results when compared to the javascript version. I use the python code in my change app to verify the password passes muster prior to changing it, so if anything I'd want it to be more strict that the client side JS version.
Password: FooBar2016
JS: score: 0, entropy: 18.541
Python: score: 2, entropy: 30.089
Password: ZagDag2016
JS: score: 2, entropy: 32.783
Python: score: 4, entropy: 44.264
If I had to choose I'd pick the JS version, the python one looks way too lenient.
(full result for FooBar2016 below.
JS:
Calling zxcvbn
{ password: 'FooBar2016',
entropy: 18.541,
match_sequence:
[ { pattern: 'dictionary',
i: 0,
j: 5,
token: 'FooBar',
matched_word: 'foobar',
rank: 908,
dictionary_name: 'passwords',
reversed: false,
base_entropy: 9.826548487290916,
uppercase_entropy: 4.392317422778761,
reversed_entropy: 0,
l33t_entropy: 0,
entropy: 14.218865910069677 },
{ pattern: 'regex',
token: '2016',
i: 6,
j: 9,
regex_name: 'recent_year',
regex_match: [Object],
entropy: 4.321928094887363 } ],
crack_time: 19.068,
crack_time_display: '19.068000000000023 seconds',
score: 0,
calc_time: 8 }
Python:
python -c 'import zxcvbn; print zxcvbn.password_strength("FooBar2016")'
{'crack_time_display': '17.0 hours', 'crack_time': 57103.66, 'score': 2, 'entropy': 30.089, 'password': 'FooBar2016', 'calc_time': 0.0005788803100585938, 'match_sequence': [{'l33t_entropy': 0, 'dictionary_name': 'passwords', 'matched_word': 'foobar', 'bas
e_entropy': 9.826548487290916, 'i': 0, 'pattern': 'dictionary', 'j': 5, 'rank': 908, 'token': 'FooBar', 'entropy': 14.285980105928214, 'uppercase_entropy': 4.459431618637297}, {'i': 6, 'pattern': 'spatial', 'j': 8, 'shifted_count': 0, 'token': '201', 'ent
ropy': 9.848831558033764, 'graph': 'keypad', 'turns': 2}, {'i': 9, 'pattern': 'bruteforce', 'j': 9, 'token': '6', 'entropy': 5.954196310386876, 'cardinality': 62}]}