klg.passwordEntropy

Yet another Javascript strength checker.

by mwgamera

HTML

<script src="https://cdn.rawgit.com/mwgamera/3803414/raw/39fd927ba36e17ceaea27710d0b5f58a526cd268/lz_passwordMinModel0.js"></script>
<script src="https://cdn.rawgit.com/mwgamera/3520024/raw/5d78ae15367d6d1ba8d349d204d49dbc7de13dcc/passwordEntropy.min.js"></script>
<script src="https://cdn.rawgit.com/mwgamera/3802251/raw/6e7e0f40027738dfc789ca62c7f931e406f652a6/lz.min.js"></script>
<div style="margin: 2em">
    <label for="pass">Password:</label>
    <input id="pass" type="password">
    <label><input id="hide" type="checkbox" checked="checked"> hide</label>
    <div id="meter"></div>
    <div id="text">
        <span id="qual"></span>
        <label for="bits"><span id="bits">0.00</span> bit</label>
    </div>
</div>

SCSS

$width: 200px;

input#pass {
    width: $width;
    border-width: 1px;
}

#meter {
    padding: 0;
    margin: 0;
}
#meter span {
    width: $width/4 - 4px;
    margin: 0 2px;
    height: 6px;
}

label[for=pass] {
    display: block;
}
#text {
    padding: 1ex 0;
}
#text > * {
    display: inline-block;
    width: $width/2;
    padding: 0;
}
#text label {
    text-align: right;
}

JavaScript

"use strict";
// The entropy estimator
var model = klg.lz.decode(klg.lz_passwordMinModel0);
var entropy = klg.passwordEntropy(model);

// Update function
var update = function() {
    var p = $(this).val();
    var s = entropy(p);
    $("#bits").text(d2f(s));
    meter(s < 40 ? 0 : s < 60 ? 1 : s < 80 ? 2 : 3);
};

// Format number with two decimal digits
var d2f = function(x) {
    var f = Math.round(100 * x) % 100;
    return Math.floor(x) + (f < 10 ? ".0" : ".") + f;
};

// GUI
$("#pass").keyup(update).click(update);
$("#hide").change(function() {
    $("#pass").prop("type", this.checked ? "password" : "text");
});
$("#meter").empty()
    .append("<span data-color='#ff0000'></span>")
    .append("<span data-color='#e28c00'></span>")
    .append("<span data-color='#adca00'></span>")
    .append("<span data-color='#00ff00'></span>")
    .children().each(function() {
        $(this).css("background-color", $(this).attr("data-color"))
    });
var meter = function(s) {
    $("#qual").text(["Bad","Poor","Fine","Good"][s]);
    for (var i = 0, c = $("#meter").children(); i < 4; i++) {
        if (i <= s)
            c.eq(i).css("display", "inline-block");
        else
            c.eq(i).css("display", "none");
    }
};

update.apply($("#pass"));