diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index bebdd6a5..04a57341 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -431,6 +431,7 @@ "Luhn Checksum", "CRC-8 Checksum", "CRC-16 Checksum", + "CRC-16-CCITT Checksum", "CRC-32 Checksum", "TCP/IP Checksum" ] diff --git a/src/core/operations/CRC16CCITTChecksum.mjs b/src/core/operations/CRC16CCITTChecksum.mjs new file mode 100644 index 00000000..592cb4aa --- /dev/null +++ b/src/core/operations/CRC16CCITTChecksum.mjs @@ -0,0 +1,62 @@ +/** + * @author mikecat + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Utils from "../Utils.mjs"; + +/** + * CRC-16-CCITT Checksum operation + */ +class CRC16CCITTChecksum extends Operation { + + /** + * CRC16CCITTChecksum constructor + */ + constructor() { + super(); + + this.name = "CRC-16-CCITT Checksum"; + this.module = "Crypto"; + this.description = "Another version of CRC-16, used in XMODEM/YMODEM protocol."; + this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check"; + this.inputType = "ArrayBuffer"; + this.outputType = "string"; + this.args = [ + ]; + + this.crcTable = []; + for (let i = 0; i < 256; i++) { + let value = i << 8; + for (let j = 0; j < 8; j++) { + value <<= 1; + if (value & 0x10000) value ^= 0x1021; + value &= 0xffff; + } + this.crcTable.push(value); + } + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (ArrayBuffer.isView(input)) { + input = new Uint8Array(input.buffer, input.byteOffset, input.byteLength); + } else { + input = new Uint8Array(input); + } + let crc = 0; + for (let i = 0; i < input.length; i++) { + crc = ((crc << 8) ^ this.crcTable[((crc >> 8) ^ input[i]) & 0xff]) & 0xffff; + } + return Utils.hex(crc, 4); + } + +} + +export default CRC16CCITTChecksum; diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs index d9af8065..92554143 100644 --- a/src/core/operations/GenerateAllHashes.mjs +++ b/src/core/operations/GenerateAllHashes.mjs @@ -29,6 +29,7 @@ import Fletcher64Checksum from "./Fletcher64Checksum.mjs"; import Adler32Checksum from "./Adler32Checksum.mjs"; import CRC8Checksum from "./CRC8Checksum.mjs"; import CRC16Checksum from "./CRC16Checksum.mjs"; +import CRC16CCITTChecksum from "./CRC16CCITTChecksum.mjs"; import CRC32Checksum from "./CRC32Checksum.mjs"; import BLAKE2b from "./BLAKE2b.mjs"; import BLAKE2s from "./BLAKE2s.mjs"; @@ -122,6 +123,7 @@ class GenerateAllHashes extends Operation { {name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []}, {name: "CRC-8", algo: (new CRC8Checksum), inputType: "arrayBuffer", params: ["CRC-8"]}, {name: "CRC-16", algo: (new CRC16Checksum), inputType: "arrayBuffer", params: []}, + {name: "CRC-16-CCITT", algo: (new CRC16CCITTChecksum), inputType: "arrayBuffer", params: []}, {name: "CRC-32", algo: (new CRC32Checksum), inputType: "arrayBuffer", params: []} ]; } diff --git a/tests/operations/tests/Checksum.mjs b/tests/operations/tests/Checksum.mjs index 142ee267..b4d2056e 100644 --- a/tests/operations/tests/Checksum.mjs +++ b/tests/operations/tests/Checksum.mjs @@ -194,6 +194,50 @@ TestRegister.addTests([ } ] }, + { + name: "CRC-16-CCITT: nothing", + input: "", + expectedOutput: "0000", + recipeConfig: [ + { + "op": "CRC-16-CCITT Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16-CCITT: basic string", + input: BASIC_STRING, + expectedOutput: "03ef", + recipeConfig: [ + { + "op": "CRC-16-CCITT Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16-CCITT: UTF-8", + input: UTF8_STR, + expectedOutput: "cf94", + recipeConfig: [ + { + "op": "CRC-16-CCITT Checksum", + "args": [] + } + ] + }, + { + name: "CRC-16-CCITT: all bytes", + input: ALL_BYTES, + expectedOutput: "7e55", + recipeConfig: [ + { + "op": "CRC-16-CCITT Checksum", + "args": [] + } + ] + }, { name: "CRC-32: nothing", input: "", diff --git a/tests/operations/tests/GenerateAllHashes.mjs b/tests/operations/tests/GenerateAllHashes.mjs index 8e4a849a..1bd4d48d 100644 --- a/tests/operations/tests/GenerateAllHashes.mjs +++ b/tests/operations/tests/GenerateAllHashes.mjs @@ -63,6 +63,7 @@ Fletcher-64: 7473657474736574 Adler-32: 045d01c1 CRC-8: b9 CRC-16: f82e +CRC-16-CCITT: 9b06 CRC-32: d87f7e0c `, recipeConfig: [