## README.md

```
<div align="center">
# `b58` - _Minimalist_ Elixir `Base58` Encoding/Decoding Library
[![Build Status](https://img.shields.io/travis/dwyl/base58/master.svg?style=flat-square)](https://travis-ci.org/dwyl/base58)
[![codecov.io](https://img.shields.io/codecov/c/github/dwyl/base58/master.svg?style=flat-square)](http://codecov.io/github/dwyl/base58?branch=master)
[![Hex.pm](https://img.shields.io/hexpm/v/b58?color=brightgreen&style=flat-square)](https://hex.pm/packages/b58)
[![Libraries.io dependency status](https://img.shields.io/librariesio/release/hex/b58?logoColor=brightgreen&style=flat-square)](https://libraries.io/hex/b58)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/base58/issues)
[![HitCount](http://hits.dwyl.com/dwyl/base58.svg)](http://hits.dwyl.com/dwyl/base58)
<!-- uncomment when service is working ...
[![Inline docs](http://inch-ci.org/github/dwyl/base58.svg?branch=master&style=flat-square)](http://inch-ci.org/github/dwyl/base58)
-->
![base58-encode-hero-image](https://user-images.githubusercontent.com/194400/80292242-1d2de500-874d-11ea-8514-91a8fdfabfde.jpg)
</div>
`Base58` provides two functions to
work with Base58 encoded strings: `Base58.encode/1` and `Base58.decode/1` <br />
`encode/1` takes an **Elixir binary** (_String, Number, etc._)
and returns a Base58 encoded String. <br />
`decode/1` receives a Base58 encoded String and returns a binary.
See the section [What is an Elixir binary?](#what-is-an-elixir-binary) for more information about the binary type in Elixir.
## How to use the module?
### 1. Add the package to you dependencies
Open your `mix.exs` file and add the following line to your `deps`:
```elixir
defp deps do
[
{:b58, "~> 1.0.2"},
]
end
```
and run `mix deps.get`
### 2. Invoke the `encode/1` function with a binary as parameter:
```elixir
Base58.encode("foo")
"bQbp"
```
### 3. Invoke the `decode/1` function with a `base58` encoded string:
```elixir
Base58.encode("hello") |> Base58.decode()
"hello"
```
<br />
See `example/example.exs` file
for a simple example of how to use the module. <br />
You can also run this example with `mix run example/example.exs`
### Note: `Integer` Values are Converted to `String`
When encoding an `Integer`
the value is converted to a `String` before encoding
so when it is decoded it will be a string e.g:
```elixir
Base58.encode(42) |> Base58.decode()
"42"
```
This isn't ideal if you _expected_ an `Integer`
but there is no way to encode the **`type`** of the data.
So if you _know_ that you need it to be an `int`,
convert it back to a numeric value with `Base58.decode_to_int/1`:
```elixir
iex(1)> Base58.encode(42) |> Base58.decode_to_int()
42
```
<br /> <br />
## Why?
## What is Base58?
A *base* is a set of characters used for representing numbers.
https://en.wikipedia.org/wiki/Base58
For example
- The base 2 (binary system) represents numbers with the digits ` 0 1`
- The base 10 (decimal system) represents numbers with the digits `0 1 2 3 4 5 6 7 8 9`.
- The base 16 (hexadecimal system) represents numbers with the digits `0 1 2 3 4 5 6 7 8 9 A B C D E F`
The `2, 10, 16` are called **radix** and represent the number of unique digits in the base.
Bases are **positional numeral systems**. This means that the place of a digit matters,
for example we can define the place for each digit of the number 423 as:
| digit | place|
| -- | -- |
| 3 | 0 |
| 2 | 1 |
| 4 | 2 |
### From a base b to decimal
To calculate the value of a number in a specific base to base 10, we are using
the place of the digit, the radix and the function exponential as following:
**423** in base b is **4 x b<sup>2</sup> + 2 x b<sup>1</sup> + 3 x b<sup>0</sup>**
So **423** in base 10 is **4 x 10<sup>2</sup> + 2 x 10<sup>1</sup> + 3 x 10<sup>0</sup>**
another example on base 16 with the number **F66**:
We know that F is 15 in base 10, then by using exponentials and places we have
**F66** is **15 x 16<sup>2</sup> + 6 x 16<sup>1</sup> + 6 * 16<sup>0</sup>** which is
**3942**
### From decimal to base b
To convert a decimal d to base b
1. Get the remainder of d by b: `rem(d, b)` and note down the result.
2. Get the integer division of d by b:`d1 = div(d, b)` and repeat the step 1 with `rem(d1, b)`
3. Stop this process when the division returns 0
4. Match each number of the sequence of remainder to the base
For example 12 in base 2 is:
```
r0 = 0 = rem(12, 2)
d0 = 6 = div(12, 2)
r1 = 0 = rem(d0, 2) = rem(6,2)
d1 = 3 = div(6, 2)
r2 = 1 = rem(d1, 2) = rem(3, 2)
d2 = 1 = div(3, 2)
r3 = 1 = rem(d2, 2) = rem(1, 2)
d3 = 0 = div(1, 2) # stop the process
# 12 in base 2 is r3 r2 r1 r0 which is 1100
```
### Decimal to base58
`base58` represents number with the follwing character set:
`123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`
where
` 0 -> "1", 1 -> "2", ..., 57 -> "z"`
If we take the process on the previous section with **65** and apply it with base58 we have:
```
r0 = 7 = rem(65, 58)
d0 = 1 = div(65, 58)
r1 = 1 = rem(1, 58)
d1 = 0 = div(1, 58) # stop the process
# r1 r0 is 1 7 and with the base58 characters 1 is 2 and 7 is 8
# So 65 in base 10 is 28 in base 58
```
Note that if a binary start with [leading zeros](https://en.wikipedia.org/wiki/Leading_zero) then
the zeros are represented as "1" in base58.
So <<0, 0, 0, 1>> is defined as "1112" in base58.
from https://en.bitcoin.it/wiki/Base58Check_encoding
> The leading character '1', which has a value of zero in base58, is reserved for representing an entire leading zero byte
For more information about the implementation of this module see the issue 1:
[How to encode a string to base58](https://github.com/dwyl/base58encode/issues/1)
Wikipedia page for Base:
https://en.wikipedia.org/wiki/Radix
## Why Base58?
The base 58 character set is a subset of the base 64 where non-alphanumeric characters
have been removed and also `0OIl` letters to keep the string easily readable.
base 58 uses comes from Bitcoin and blockchain. It is also used with [IPFS](https://ipfs.io/)
to create [Content Identifier](https://github.com/dwyl/cid/)
Wikipedia page for base58:
https://en.wikipedia.org/wiki/Base58
## What is an Elixir binary?
From https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html
> A `binary` is a sequence of bytes
A byte is a sequence of eight bits (i.e a sequence of eight 0 or 1)
For example the following are bytes with their decimal representation:
| byte in base2 | decimal|
| -- | -- |
| 00000001 | 1 |
| 00000010 | 2 |
| 00000011 | 3 |
| 00000100 | 4 |
In Elixir binary is represented and created with `<< >>`
For example the sequence of bytes `00000001 00000010 00000011 00000100`
is `<<1, 2, 3, 4>>` in Elixir.
All Elixir Strings are a binaries but not all binaries are Strings.
A String is a binary where the numbers represent each letter in UTF8/unicode.
One trick to see the binary representation of a string is to add `<<0>>` at the end of the string with the concatenation operator `<>`:
```
"hello" <> <<0>>
<<104, 101, 108, 108, 111, 0>>
"hello" == <<104, 101, 108, 108, 111 >>
true
```
**A binary in Elixir is different to a [binary number](https://en.wikipedia.org/wiki/Binary_number) which is the representation of a number in base2, e.g 110 represents 6**
However 6 in Elixir is not a binary but an Integer.
You can use the `Integer.to_string` function to see the representation of an integer in different base:
```
Integer.to_string(6, 2) # 6 as binary number in base 2
"110"
Integer.to_string(10, 2) # 10 as binary number in base 2
"1010"
Integer.to_string(10, 10) # 10 as a decimal number in base 10
"10"
Integer.to_string(10, 16) # 10 as an hexadecimal number in base 16
"A"
Integer.to_string(15, 16) # 15 as an hexadecimal number in base 16
"F"
```
```