# zxcvbn for Elixir (Rust NIF) [![hex.pm](https://img.shields.io/hexpm/v/zxcvbn_nif.svg?style=flat-square)](https://hex.pm/packages/zxcvbn_nif) [![hexdocs.pm](https://img.shields.io/badge/docs-latest-green.svg?style=flat-square)](https://hexdocs.pm/zxcvbn_nif)
This library is based on the [zxcvbn-rs](https://github.com/shssoichiro/zxcvbn-rs) package written in Rust. It is ported to Elixir as a NIF and offers significantly improved performance over other Elixir libraries.
For more general information, see the original [zxcvbn](https://github.com/dropbox/zxcvbn) package by Dropbox.
## Installation
The package is [available in Hex](https://hex.pm/packages/zxcvbn_nif) and can be installed
by adding `zxcvbn_nif` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:zxcvbn_nif, "~> 1.0"}
]
end
```
## Usage
Full documentation is published here: [https://hexdocs.pm/zxcvbn_nif](https://hexdocs.pm/zxcvbn_nif).
Just call `Zxcvbn.run/1` with a password to analyse:
```elixir
iex> Zxcvbn.run("password")
{:ok,
%{
calc_time: 1.0761590003967285,
crack_times_display: %{
offline_fast_hashing_1e10_per_second: "less than a second",
offline_slow_hashing_1e4_per_second: "less than a second",
online_no_throttling_10_per_second: "less than a second",
online_throttling_100_per_hour: "1 minute"
},
feedback: %{
suggestions: ["Add another word or two. Uncommon words are better.",
"Reversed words aren't much harder to guess."],
warning: "This is similar to a commonly used password."
},
guesses: 3,
guesses_log10: 0.47712125471966244,
score: 0
}}
```
You can also supply a second optional parameter, to use your own word dictionary:
```elixir
iex> Zxcvbn.run("konnibanwa", ["konni", "banwa"])
{:ok,
%{
calc_time: 0.6378800272941589,
crack_times_display: %{
offline_fast_hashing_1e10_per_second: "less than a second",
offline_slow_hashing_1e4_per_second: "1 second",
online_no_throttling_10_per_second: "25 minutes",
online_throttling_100_per_hour: "6 days"
},
feedback: %{
suggestions: ["Add another word or two. Uncommon words are better."],
warning: nil
},
guesses: 15000,
guesses_log10: 4.176091259055681,
score: 1
}}
```
To compare, here is the result without using a custom dictionary:
```elixir
iex> Zxcvbn.run("konnibanwa")
{:ok,
%{
calc_time: 0.49091002345085144,
crack_times_display: %{
offline_fast_hashing_1e10_per_second: "less than a second",
offline_slow_hashing_1e4_per_second: "10 days",
online_no_throttling_10_per_second: "29 years",
online_throttling_100_per_hour: "centuries"
},
feedback: %{suggestions: nil, warning: nil},
guesses: 9460000000,
guesses_log10: 9.975891136401792,
score: 3
}}
```
## Benchmarks
Compared to [zxcvbn](https://hex.pm/packages/zxcvbn) (pure Elixir) package:
```
Operating System: macOS
CPU Information: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
Number of Available Cores: 4
Available memory: 16 GB
Elixir 1.9.2
Erlang 21.0.3
##### With input Password: elixir nifs are great #####
Name ips average deviation median 99th %
zxcvbn-nif 785.01 1.27 ms ±26.05% 1.21 ms 2.42 ms
zxcvbn-elixir 37.51 26.66 ms ±15.42% 25.99 ms 50.74 ms
Comparison:
zxcvbn-nif 785.01
zxcvbn-elixir 37.51 - 20.93x slower +25.38 ms
##### With input Password: password #####
Name ips average deviation median 99th %
zxcvbn-nif 3.51 K 0.29 ms ±68.93% 0.27 ms 0.43 ms
zxcvbn-elixir 0.0397 K 25.22 ms ±12.50% 24.72 ms 43.75 ms
Comparison:
zxcvbn-nif 3.51 K
zxcvbn-elixir 0.0397 K - 88.44x slower +24.93 ms
```
## License
See LICENSE file.