Packages

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

Current section

Files

Jump to
ex_crc lib ex_crc.ex
Raw

lib/ex_crc.ex

defmodule ExCRC do
@moduledoc """
Calculate CRC checksums
"""
use Bitwise
# poly=0x1021, start=0xffff, check=0x29b1
@doc """
Compute and return the CRC16/CCITT-FALSE checksum of a binary _value_.
"""
@spec crc16ccitt(value :: binary) :: non_neg_integer
def crc16ccitt(value) do
import ExCRC.Tables, only: [ccitt_table: 0]
calc_ccitt(:binary.bin_to_list(value), 0xffff, ccitt_table())
end
# poly=0x1021, start=0x0000, check=0x2189, refin=yes, refout=yes
@doc """
Compute and return the CRC16/CCITT-TRUE checksum of a binary _value_
"""
@spec crc16kermit(value :: binary) :: non_neg_integer
def crc16kermit(value) do
import ExCRC.Tables, only: [kermit_table: 0]
calc_kermit(:binary.bin_to_list(value), 0x0000, kermit_table())
end
# poly=0x1021, start=0x0000, check=0x31c3
@doc """
Compute and return the CRC16/XMODEM checksum of a binary _value_.
"""
@spec crc16xmodem(value :: binary) :: non_neg_integer
def crc16xmodem(value) do
import ExCRC.Tables, only: [ccitt_table: 0]
calc_ccitt(:binary.bin_to_list(value), 0x0000, ccitt_table())
end
# Calculate CRC using ccitt table
@spec calc_ccitt([byte], non_neg_integer, table :: map) :: non_neg_integer
defp calc_ccitt([x | rem], crc, table) do
key = ((crc >>> 8) ^^^ x) &&& 0xff
crc = (crc <<< 8) ^^^ Map.get(table, key)
calc_ccitt(rem, crc &&& 0xffff, table)
end
defp calc_ccitt([], crc, _), do: crc
# Calculate CRC using kermit table
@spec calc_kermit([byte], non_neg_integer, table :: map) :: non_neg_integer
defp calc_kermit([x | rem], crc, table) do
key = (crc ^^^ x) &&& 0xff
crc = (crc >>> 8) ^^^ Map.get(table, key)
calc_kermit(rem, crc &&& 0xffff, table)
end
defp calc_kermit([], crc, _) do
low_byte = (crc &&& 0xff00) >>> 8
high_byte = (crc &&& 0x00ff) <<< 8
low_byte ||| high_byte
end
end