lojic / triangledevs-codex

Resources for the Triangle Devs Slack #codex channel

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Password Strength Indicator

lojic opened this issue · comments

Password Strength Indicator

Write a function to indicate the strength of a password.

Inputs

  • username :: String
  • password :: String
  • lookup_word :: String -> Boolean

The lookup_word function accepts a word and indicates whether the word exists in a dictionary. Use the provided dictionary.txt from the repository to create this function.

Output

The result is a 2-tuple of (level, message) where level is one of { Fail, Weak, Fair, Good, Strong }, and message indicates the failure(s) if there are any. For successful results, message can be "", nil, null, #f, etc. as appropriate for your language.

Character Set Size

Determine the size of the character set used by the password.

  • Digits only = 10
  • Lower case only = 26
  • Upper case only = 26
  • Symbols only = 32 i.e. ~ ` ! @ # $ % ^ & * ( ) - _ = + [ ] { } \ | ; : ' " / ? . > , <

For example, if the password contains only digits and lower case characters, the character set size would be 36. If it contains all four types of characters, the character set size would be 94. Combinations can yield character set sizes in { 10, 26, 32, 36, 42, 52, 58, 62, 68, 84, 94 }.

Entropy Bits

Given the character set size (C) in use, and the length (L) of the password, the number of possible passwords is C ^ L. To determine the number of bits (B) necessary to represent this number, we have: 2 ^ B = C ^ L. Solving for B gives: B = ceiling(L * log2(C))

For example, suppose the password is "Open-Sesame". The character set size (C) is 32 + 26 + 26 = 84. The length (L) is 11. So the number of entropy bits (rounded) is: ceiling(11 * log2(84)) = 71

Failed Passwords

A password fails if any of the following conditions are met:

  • Entropy bits < 48
  • Contains the username
  • Contains one, or more dictionary words of 3 characters or more

Examples

For the examples, assume a username of jsmith

  • "Pswd1" -> (Fail, "entropy bits (30) < 48")
  • "FgKMsFqEjsmithZ4UIMw7pkmT4e4" (Fail, "Contains username (jsmith); Contains dictionary words: mit, smith, smit")
  • "abate" (Fail, "entropy bits (24) < 48, and contains dictionary words abate, bat, bate, ate")

Strength Indication

If a password does not fail, the strength is calculated as follows:

  • Entropy bits in [48, 66) ==> Weak e.g. "a4df8az2wq" w/ 52 entropy bits
  • Entropy bits in [66, 99) ==> Fair e.g. "A4dF8aZ2wQ5" w/ 66 entropy bits
  • Entropy bits in [99, 132) ==> Good e.g. "Ab@hY#iU*qw!fv$z" w/ 103 entropy bits
  • Entropy bits in [132, inf) ==> Strong e.g. "!1Qa@2Ws#3Ed$4Rf%5Tg" w/ 132 entropy bits

The spec didn't address whitespace. For my implementation, I will not consider whitespace in the password.