goluhn: A simple package for generating, calculating and verifying luhn numbers
Tags: go, opensource, fintech
Published: 2019-11-21 14:09:52

> This short article will introduce you to `goluhn`, a very simple go package to apply luhn numbers to your projects.

# What is a luhn number 

A luhn number is **a number whose last digit satisfies the luhn checksum formula**. It is named after its inventor Hans Peter Luhn. For example, in the luhn number `1111 2222 3333 4444`, the last `4` digit is the luhn checksum digit of the number. 

## Intended use and application

The **most popular use** of a luhn number is a credit card number. Every credit card number satisfies the luhn algorithm. Luhn numbers are also used for other identification methods such as `IMEI numbers`, electricity meter numbers, various countries' ID numbers and so on.

The luhn check is **mainly designed** to protect against accidentally entered numbers, basically typos. It is not designed to protect against malicious checks. Therefore validation of these number is the main use case.

# Using `goluhn`

Using `goluhn` is extremely simple. It exposes three functions `Validate`, `Calculate` and `Generate`.

{% github https://github.com/ShiraazMoollatjie/goluhn no-readme %}

To kick things off, we start with the package import:

```go
import "github.com/ShiraazMoollatjie/goluhn"
```

## Validate
We call the `Validate` function to **validate whether a provided string is a luhn number**. Invalid luhn strings return errors.

```go
err := goluhn.Validate("1111222233334444")
if err != nil {
  return err
}
```

## Calculation
This is used when we have a numeric string whose **luhn check digit needs to be calculated**. 

```go
cd, n, err := goluhn.Calculate("111122223333444")
if err != nil {
  return err
}

fmt.Printf("Check digit: %s\n", cd)
fmt.Printf("Luhn number: %s\n", n)
```

This function will return the check digit as well as the original with the luhn digit appended to it.

## Generate

The `Generate` function will **generate a random luhn number of a provided length**. This is useful for when you are generating your own numbers in your system. In the example below, we generate luhn numbers of length 16 (effectively a credit card number).

```go
n, err := goluhn.Generate(16)
if err != nil {
  return err
}

fmt.Printf("Luhn number: %s\n", n)
```

# Random Thoughts

This project was quick and fun to implement. I decided to **use strings over integers** because it is possible to generate luhn numbers for numbers that are greater than the `int64` type (this is fun to try out actually). There are no real numeric operations that apply to luhn numbers, so this also motivated me to use strings instead. Strings also allow for zero padded prefixed numbers to be generated.

The `Validate` function arguably **could have returned a `bool, error` result**. I don't really like returning that specific combination of types because either you have an error or the result of the function is free from errors which implies true. Additionally, I think that if you returned a boolean `false` in this specific case, you're very likely to return an error too.

# Conclusion

In this article, we learnt how to use `goluhn` to generate luhn numbers. We also delved a bit into some of the design decisions. As always, **contributions are always welcomed!**

# References

[The wikipedia entry](https://en.wikipedia.org/wiki/Luhn_algorithm)