/* crc16.pk - Pickle for CRC algorithms with 16-bits.  */

/* Copyright (C) 2024, 2025 The poke authors.  */

/* This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

var CRC16_CCITT_TABLE = [
  0x0000UH, 0x1021UH, 0x2042UH, 0x3063UH, 0x4084UH, 0x50a5UH, 0x60c6UH,
  0x70e7UH, 0x8108UH, 0x9129UH, 0xa14aUH, 0xb16bUH, 0xc18cUH, 0xd1adUH,
  0xe1ceUH, 0xf1efUH, 0x1231UH, 0x0210UH, 0x3273UH, 0x2252UH, 0x52b5UH,
  0x4294UH, 0x72f7UH, 0x62d6UH, 0x9339UH, 0x8318UH, 0xb37bUH, 0xa35aUH,
  0xd3bdUH, 0xc39cUH, 0xf3ffUH, 0xe3deUH, 0x2462UH, 0x3443UH, 0x0420UH,
  0x1401UH, 0x64e6UH, 0x74c7UH, 0x44a4UH, 0x5485UH, 0xa56aUH, 0xb54bUH,
  0x8528UH, 0x9509UH, 0xe5eeUH, 0xf5cfUH, 0xc5acUH, 0xd58dUH, 0x3653UH,
  0x2672UH, 0x1611UH, 0x0630UH, 0x76d7UH, 0x66f6UH, 0x5695UH, 0x46b4UH,
  0xb75bUH, 0xa77aUH, 0x9719UH, 0x8738UH, 0xf7dfUH, 0xe7feUH, 0xd79dUH,
  0xc7bcUH, 0x48c4UH, 0x58e5UH, 0x6886UH, 0x78a7UH, 0x0840UH, 0x1861UH,
  0x2802UH, 0x3823UH, 0xc9ccUH, 0xd9edUH, 0xe98eUH, 0xf9afUH, 0x8948UH,
  0x9969UH, 0xa90aUH, 0xb92bUH, 0x5af5UH, 0x4ad4UH, 0x7ab7UH, 0x6a96UH,
  0x1a71UH, 0x0a50UH, 0x3a33UH, 0x2a12UH, 0xdbfdUH, 0xcbdcUH, 0xfbbfUH,
  0xeb9eUH, 0x9b79UH, 0x8b58UH, 0xbb3bUH, 0xab1aUH, 0x6ca6UH, 0x7c87UH,
  0x4ce4UH, 0x5cc5UH, 0x2c22UH, 0x3c03UH, 0x0c60UH, 0x1c41UH, 0xedaeUH,
  0xfd8fUH, 0xcdecUH, 0xddcdUH, 0xad2aUH, 0xbd0bUH, 0x8d68UH, 0x9d49UH,
  0x7e97UH, 0x6eb6UH, 0x5ed5UH, 0x4ef4UH, 0x3e13UH, 0x2e32UH, 0x1e51UH,
  0x0e70UH, 0xff9fUH, 0xefbeUH, 0xdfddUH, 0xcffcUH, 0xbf1bUH, 0xaf3aUH,
  0x9f59UH, 0x8f78UH, 0x9188UH, 0x81a9UH, 0xb1caUH, 0xa1ebUH, 0xd10cUH,
  0xc12dUH, 0xf14eUH, 0xe16fUH, 0x1080UH, 0x00a1UH, 0x30c2UH, 0x20e3UH,
  0x5004UH, 0x4025UH, 0x7046UH, 0x6067UH, 0x83b9UH, 0x9398UH, 0xa3fbUH,
  0xb3daUH, 0xc33dUH, 0xd31cUH, 0xe37fUH, 0xf35eUH, 0x02b1UH, 0x1290UH,
  0x22f3UH, 0x32d2UH, 0x4235UH, 0x5214UH, 0x6277UH, 0x7256UH, 0xb5eaUH,
  0xa5cbUH, 0x95a8UH, 0x8589UH, 0xf56eUH, 0xe54fUH, 0xd52cUH, 0xc50dUH,
  0x34e2UH, 0x24c3UH, 0x14a0UH, 0x0481UH, 0x7466UH, 0x6447UH, 0x5424UH,
  0x4405UH, 0xa7dbUH, 0xb7faUH, 0x8799UH, 0x97b8UH, 0xe75fUH, 0xf77eUH,
  0xc71dUH, 0xd73cUH, 0x26d3UH, 0x36f2UH, 0x0691UH, 0x16b0UH, 0x6657UH,
  0x7676UH, 0x4615UH, 0x5634UH, 0xd94cUH, 0xc96dUH, 0xf90eUH, 0xe92fUH,
  0x99c8UH, 0x89e9UH, 0xb98aUH, 0xa9abUH, 0x5844UH, 0x4865UH, 0x7806UH,
  0x6827UH, 0x18c0UH, 0x08e1UH, 0x3882UH, 0x28a3UH, 0xcb7dUH, 0xdb5cUH,
  0xeb3fUH, 0xfb1eUH, 0x8bf9UH, 0x9bd8UH, 0xabbbUH, 0xbb9aUH, 0x4a75UH,
  0x5a54UH, 0x6a37UH, 0x7a16UH, 0x0af1UH, 0x1ad0UH, 0x2ab3UH, 0x3a92UH,
  0xfd2eUH, 0xed0fUH, 0xdd6cUH, 0xcd4dUH, 0xbdaaUH, 0xad8bUH, 0x9de8UH,
  0x8dc9UH, 0x7c26UH, 0x6c07UH, 0x5c64UH, 0x4c45UH, 0x3ca2UH, 0x2c83UH,
  0x1ce0UH, 0x0cc1UH, 0xef1fUH, 0xff3eUH, 0xcf5dUH, 0xdf7cUH, 0xaf9bUH,
  0xbfbaUH, 0x8fd9UH, 0x9ff8UH, 0x6e17UH, 0x7e36UH, 0x4e55UH, 0x5e74UH,
  0x2e93UH, 0x3eb2UH, 0x0ed1UH, 0x1ef0UH,
];

/* CRC-CCITT
 *
 * Other names:
 *   - CRC-16/IBM-3740
 *   - CRC-16/AUTOSAR
 *   - CRC-16/CCITT-FALSE
 *
 * Poly=0x1021 Init=0xffff RefIn=false RefOut=false XorOut=0x0000
 */

fun crc16_ccitt = (uint<8>[] data) uint<16>:
{

  var c = 0xffffUH;

  for (b in data)
    c = CRC16_CCITT_TABLE[(c .>> 8) ^ b] ^ (c <<. 8);
  return c;
}
