Packages

Library that enables programs to write Data Matrix barcodes of the modern ECC200 variety.

Current section

Files

Jump to
data_matrix lib datamatrix reed_solomon.ex
Raw

lib/datamatrix/reed_solomon.ex

defmodule DataMatrix.ReedSolomon do
import Bitwise
alias DataMatrix.GaloisField
@doc """
iex> DataMatrix.ReedSolomon.encode(<<142, 164, 186>>, 5)
<<114, 25, 5, 88, 102>>
"""
def encode(data, length) do
coefficients = gen_poly(length)
Enum.reduce(
:binary.bin_to_list(data),
Stream.cycle([0]) |> Enum.take(length + 1),
fn codeword, acc ->
k = Enum.at(acc, 0) ^^^ codeword
acc =
for j <- 0..(length - 1),
do: Enum.at(acc, j + 1) ^^^ prod(k, elem(coefficients, length - j - 1))
Enum.concat(acc, [0])
end
)
|> Enum.take(length)
|> :binary.list_to_bin()
end
def gen_poly(nc) do
# coefficients
c = Tuple.duplicate(0, nc + 1)
Enum.reduce(1..nc, put_elem(c, 0, 1), fn i, c ->
c = put_elem(c, i, elem(c, i - 1))
c =
if i - 1 >= 1 do
Enum.reduce((i - 1)..1, c, fn j, c ->
value = elem(c, j - 1) ^^^ prod(elem(c, j), GaloisField.antilog(i))
put_elem(c, j, value)
end)
else
c
end
put_elem(c, 0, prod(elem(c, 0), GaloisField.antilog(i)))
end)
end
defp prod(0, _) do
0
end
defp prod(_, 0) do
0
end
defp prod(a, b) do
GaloisField.antilog(rem(GaloisField.log(a) + GaloisField.log(b), 255))
end
end