Packages

Pure Elixir implementation of CRC16 algorithm in a few different variants.

Current section

Files

Jump to
ex_crc lib generator.ex
Raw

lib/generator.ex

defmodule ExCRC.Generator do
@moduledoc """
Functions used to generate the static tables included by this library
"""
use Bitwise
#
# Provide `print_crc_table/2` with a map and it will print the
# map in Elixir syntax which can be used statically. This is used to
# generate the tables in the `ExCRC.Tables` module.
#
def print_crc_table(table, width \\ 4) do
data =
table
|> Enum.to_list()
|> List.keysort(0)
|> Enum.map(fn({k,v}) ->
key = :io_lib.format("~2.16.0b", [k])
value = :io_lib.format("~4.16.0b", [v])
"0x#{key} => 0x#{value}"
end)
|> Enum.chunk_every(width, width, [])
|> Enum.map(fn(row) -> Enum.join(row, ", ") end)
|> Enum.map(fn(row) -> " #{row}," end)
|> Enum.join("\n")
trimmed =
data
|> String.trim_trailing("\n")
|> String.trim_trailing(",")
IO.puts("%{\n#{trimmed}\n}")
end
# Build the table data for polynomial 0x1021, return a map
def ccitt_table() do
for i <- 0..255, into: %{} do
crc = 0
c = i <<< 8
{i, ccitt_entry(c, crc, 0, 0x1021) &&& 0xffff}
end
end
# Compute a entry
defp ccitt_entry(_, crc, 8, _), do: crc
defp ccitt_entry(c, crc, bc, polynom) do
case (crc ^^^ c) &&& 0x8000 do
0 -> ccitt_entry(c <<< 1, crc <<< 1, bc + 1, polynom)
_ -> ccitt_entry(c <<< 1, (crc <<< 1) ^^^ polynom, bc + 1, polynom)
end
end
# Build the table data for polynomial 0x8408, return a map
def kermit_table() do
for i <- 0..255, into: %{} do
crc = 0
c = i
{i, kermit_entry(c, crc, 0, 0x8408) &&& 0xffff}
end
end
# Compute a entry
defp kermit_entry(_, crc, 8, _), do: crc
defp kermit_entry(c, crc, bc, polynom) do
case (crc ^^^ c) &&& 1 do
0 -> kermit_entry(c >>> 1, crc >>> 1, bc + 1, polynom)
_ -> kermit_entry(c >>> 1, (crc >>> 1) ^^^ polynom, bc + 1, polynom)
end
end
end