Потребовалось проверить CRC8 файла на маршрутизаторе Mikrotik. Поиск в Интернете ничего не дал. Написал сам.
На вход функции подаётся, первым и вторым аргументом соответственно, строка и её длина. Почему бы длину стоки не посчитать в самой функции? Потому, что иногда бывает нужно проверить не всю строку, а только её часть.
Входные данные не проверяются из соображения скорости выполнения и объёма кода.
В строке разрешены только символы с кодами от 0x0 до 0x7F (см. ниже). Если этого не достаточно, но необходимо расширить таблицу :local tbl.
Начальное значение — 0x0, полином — 0x7.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
: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 } |
Проверяем:
1 2 |
:put [$crc8 "123456789" 9] >>F4 |
Т.к в Mikrotik невозможно получить код символа, то приходится брать символ, искать его в таблице, а уж позиция в таблице будет кодом символа.