Skip to content

Instantly share code, notes, and snippets.

@nathany nathany/luhn.ex
Last active Dec 28, 2016

Embed
What would you like to do?
Luhn algorithm to checksum credit cards.
defmodule Luhn do
@moduledoc """
Luhn algorithm to checksum credit cards.
"""
@doc """
Check if a credit card number is valid based on luhn.
"""
def valid?(cc) when is_integer(cc) do
Integer.digits(cc)
|> Enum.reverse
|> Enum.with_index
|> Enum.map(&double_digit(&1))
|> Enum.sum
|> divisible?(10)
end
def valid?(cc) when is_binary(cc) do
case Integer.parse(cc) do
{int, ""} -> valid?(int)
_ -> false
end
end
defp divisible?(left, right) do
rem(left, right) == 0
end
require Integer
# double every second digit
defp double_digit({digit, index}) when Integer.is_odd(index) do
digit = digit * 2
# 10 = 1+0, 18 = 1+8
if digit > 9, do: digit - 9, else: digit
end
defp double_digit({digit, _}), do: digit
end
package card
// luhn checks if a credit card number is valid based on the luhn algorithm.
func luhn(cc string) bool {
var odd bool
var sum int
// start from the right side
for i := len(cc) - 1; i >= 0; i-- {
digit := int(cc[i] - '0')
if digit < 0 || digit > 9 {
return false
}
// double every second digit
if odd {
digit *= 2
// 10 = 1+0, 18 = 1+8
if digit > 9 {
digit -= 9
}
}
odd = !odd
sum += digit
}
return sum%10 == 0
}
@maxguzenski

This comment has been minimized.

Copy link

maxguzenski commented Aug 4, 2016

https://www.rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Elixir

  def valid?(cc) when is_integer(cc) do
    0 == Integer.digits(cc)
      |> Enum.reverse
      |> Enum.chunk(2, 2, [0])
      |> Enum.reduce(0, fn([odd, even], sum) -> Enum.sum([sum, odd | Integer.digits(even*2)]) end)
      |> rem(10)
  end
@minhajuddin

This comment has been minimized.

Copy link

minhajuddin commented Dec 28, 2016

@maxguzenski Nice 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.