Last active
July 3, 2016 08:23
-
-
Save fishtreesugar/8da90b6c06918b4e429b513c24cfaaaf to your computer and use it in GitHub Desktop.
util functions in Elixir for Chinese ID
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule CnId do | |
defp parse!(id) do | |
<<adcode :: 6-bytes, year :: 4-bytes, month :: 2-bytes, day :: 2-bytes, seq_code :: 3-bytes, check_code :: 1-bytes>> = id | |
%{ | |
adcode: adcode, | |
birthday: Date.from_iso8601!("#{year}-#{month}-#{day}"), | |
seq_code: seq_code, | |
check_code: check_code | |
} | |
end | |
def checksum(id) do | |
<<info :: 17-bytes, check_code :: 1-bytes>> = id | |
Stream.iterate(18, &(&1 - 1)) | |
|> Stream.zip(String.to_charlist(info)) | |
|> Enum.reduce(0, fn {index, char}, acc -> | |
n = char - ?0 | |
acc + n * rem(round(:math.pow(2, index - 1)), 11) | |
end) | |
|> (&(rem(12 - rem(&1, 11), 11))).() | |
|> (&(if &1 < 10, do: to_string(&1), else: "X")).() | |
end | |
def validate?(id) do | |
<<info :: 17-bytes, check_code :: 1-bytes>> = id | |
checksum(id) == check_code | |
end | |
def adcode(id) do | |
parse!(id).adcode | |
end | |
def seq_code(id) do | |
parse!(id).seq_code | |
end | |
def birthday(id) do | |
parse!(id).birthday | |
end | |
def gender(id) do | |
seq_code(id) | |
|> Integer.parse | |
|> elem(0) | |
|> rem(2) | |
|> (&(if &1 == 0, do: :female, else: :male)).() | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment