CPF

A library to work with CPFs.

Hex pm CircleCI Coverage Status

CPF is an acronym for "Cadastro de Pessoa Físicas," it's a unique number associated to a person that the Brazilian government maintains. With this number, it is possible to check or retrieve information about a person.

This library provides a validation that checks if the number is a valid CPF number. The CPF has check digit algorithm is similar to ISBN 10, you can check the details in Portuguese here.

Installation

If available in Hex, the package can be installed by adding cpf to your list of dependencies in mix.exs:

def deps do
  [
    {:cpf, "~> 0.5"}
  ]
end

Quick Start

You verify if the CPF is valid by calling the function CPF.valid?/1:

iex> CPF.valid?(563_606_676_73)
true

iex> CPF.valid?(563_606_676_72)
false

iex> CPF.valid?("563.606.676-73")
true

iex> CPF.valid?("563.606.676-72")
false

iex> CPF.valid?("56360667673")
true

iex> CPF.valid?("56360667672")
false

Parsing and Storing CPFs

If you want to store CPF as integer or as String.t, this library have you covered. You can do:

iex> "044.858.476-08" |> CPF.parse!() |> CPF.to_integer()
4485847608

iex> "044.858.476-08" |> CPF.parse!() |> to_string()
"04485847608"

Storing CPF as strings are easier for a human to read since the 0 padding digits are there. Meanwhile, storing as integers will allow you have better performance in CPF lookups.

The CPF.parse/1 and CPF.parse!/1 returns you the CPF value wrapped in a custom type with explicit digits.

iex> CPF.parse("044.858.476-08")
{:ok, #CPF<"044.858.476-08">}

iex> CPF.parse("044.858.476-07")
{:error, %CPF.ParsingError{reason: :invalid_verifier}}

iex> CPF.parse!("044.858.476-08")
#CPF<"044.858.476-08">

iex> CPF.parse!("044.858.476-07")
** (CPF.ParsingError) invalid verifier

With the casted CPF in hands, you can use CPF.format/1, CPF.to_integer/1 and to_string/1.

CPF Formatting

If you have a valid CPF strings or integer in hands, you can use CPF.new/1 and in sequence call CPF.format/1:

iex> 4485847608 |> CPF.new() |> CPF.format()
"044.858.476-08"

iex> "04485847608" |> CPF.new() |> CPF.format()
"044.858.476-08"

The CPF.format/1 expects the input be wrapped in the CPF type. Remember, only use CPF.new with valid CPFs, no other checks are done there. If you need some validation, use CPF.parse/1.

Why not other libraries?

This library runs 3 times faster and consume 3 times less memory and work with primitive types, no extra struct is necessary.

Docs

The docs can be found at https://hexdocs.pm/cpf.