/* $Id: crc16_arc.cs $ * Last updated: * $Date: 2019-11-23 07:07Z $ * $Version: 1.1 $ */ /******************************* LICENSE *********************************** * Copyright (C) 2019 David Ireland, DI Management Services Pty Limited. * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net> * The code in this module is licensed under the terms of the MIT license. * For a copy, see <http://opensource.org/licenses/MIT> **************************************************************************** */ using System; using System.Text; using System.Diagnostics; namespace crc16 { /* Compute CRC-16 checksum over input string. Ref: Catalogue of parametrised CRC algorithms with 16 bits http://reveng.sourceforge.net/crc-catalogue/16.htm CRC-16/ARC Alias: ARC, CRC-16, CRC-16/LHA, CRC-IBM width=16 poly=0x8005 init=0x0000 refin=true refout=true xorout=0x0000 check=0xbb3d residue=0x0000 name="CRC-16/ARC" CRC('123456789')=bb3d */ class crc16_arc { static void Main(string[] args) { // Standard check CheckTest("123456789", 0xbb3d); // Other tests CheckTest("hello world", 0x39c1); CheckTest("a", 0xe8c1); CheckTest(" ", 0xd801); CheckTest("", 0x0000); } static bool CheckTest(string msg, UInt16 check) { UInt16 crc; crc = crc16(msg); Console.WriteLine("CRC-16('{0}')={1:X4}, CHECK={2:X4}", msg, crc, check); Debug.Assert(crc == check, "CRC check failed"); return (crc == check); } /// <summary> /// Compute CRC-16/ARC checksum over input string. /// </summary> /// <param name="Str">Input string</param> /// <returns>CRC value as 16-bit unsigned integer</returns> static UInt16 crc16(string Str) { const UInt16 INIT = 0x0000; const UInt16 POLY = 0xA001; // 0x8005 with bits reversed const UInt16 XOUT = 0x0000; // Convert string to byte array byte[] b = System.Text.Encoding.Default.GetBytes(Str); int len = b.Length; UInt16 temp; int i, j; UInt16 crc = INIT; for (i = 0; i < len; i++) { temp = (UInt16)((crc & 0xFF) ^ b[i]); for (j = 0; j < 8; j++) { if ((temp & 0x1) > 0) temp = (UInt16)((temp >> 1) ^ POLY); else temp >>= 1; } crc = (UInt16)((crc >> 8) ^ temp); } return (UInt16)(crc ^ XOUT); } } }