Потребовалось проверить CRC8 файла на маршрутизаторе Mikrotik. Поиск в Интернете ничего не дал. Написал сам.
На вход функции подаётся, первым и вторым аргументом соответственно, строка и её длина. Почему бы длину стоки не посчитать в самой функции? Потому, что иногда бывает нужно проверить не всю строку, а только её часть.
Входные данные не проверяются из соображения скорости выполнения и объёма кода.
В строке разрешены только символы с кодами от 0x0 до 0x7F (см. ниже). Если этого не достаточно, но необходимо расширить таблицу :local tbl.
Начальное значение — 0x0, полином — 0x7.
:global crc8 do={
:local crc 0
:local poly 0x7
:local tbl ( "\00", "\01", "\02", "\03", "\04", "\05", "\06", "\07", "\08", "\09", "\0A", "\0B", "\0C", "\0D", "\0E", "\0F", \
"\10", "\11", "\12", "\13", "\14", "\15", "\16", "\17", "\18", "\19", "\1A", "\1B", "\1C", "\1D", "\1E", "\1F", \
"\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", "\28", "\29", "\2A", "\2B", "\2C", "\2D", "\2E", "\2F", \
"\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", "\38", "\39", "\3A", "\3B", "\3C", "\3D", "\3E", "\3F", \
"\40", "\41", "\42", "\43", "\44", "\45", "\46", "\47", "\48", "\49", "\4A", "\4B", "\4C", "\4D", "\4E", "\4F", \
"\50", "\51", "\52", "\53", "\54", "\55", "\56", "\57", "\58", "\59", "\5A", "\5B", "\5C", "\5D", "\5E", "\5F", \
"\60", "\61", "\62", "\63", "\64", "\65", "\66", "\67", "\68", "\69", "\6A", "\6B", "\6C", "\6D", "\6E", "\6F", \
"\70", "\71", "\72", "\73", "\74", "\75", "\76", "\77", "\78", "\79", "\7A", "\7B", "\7C", "\7D", "\7E", "\7F" )
for i from=0 to=($2 - 1) do={
:local chr [:pick $1 $i ($i + 1)]
set $crc ($crc ^ [:find $tbl $chr])
for j from=0 to=7 do={
if ($crc & 0x80 = 0) do={
set $crc ($crc << 1)
} else={
:set $crc ((($crc << 1) & 0xFF) ^ $poly)
}
}
}
:local crchex
if ($crc & 0xF0 > 0x90) do={
:set crchex [:pick $tbl (($crc >> 4) + 0x37)]
} else={
:set crchex [:pick $tbl (($crc >> 4) + 0x30)]
}
if ($crc & 0x0F > 9) do={
:set crchex ($crchex.[:pick $tbl (($crc & 0xF) + 0x37)])
} else={
:set crchex ($crchex.[:pick $tbl (($crc & 0xF) + 0x30)])
}
:return $crchex
}
Проверяем:
:put [$crc8 "123456789" 9] >>F4
Т.к в Mikrotik невозможно получить код символа, то приходится брать символ, искать его в таблице, а уж позиция в таблице будет кодом символа.