diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index bebdd6a5e..19ef01bc0 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -74,7 +74,9 @@ "CBOR Decode", "Caret/M-decode", "Rison Encode", - "Rison Decode" + "Rison Decode", + "Bytes to Long", + "Long to Bytes" ] }, { diff --git a/src/core/operations/BytesToLong.mjs b/src/core/operations/BytesToLong.mjs new file mode 100644 index 000000000..cc8f281cf --- /dev/null +++ b/src/core/operations/BytesToLong.mjs @@ -0,0 +1,50 @@ +/** + * @author clubby789 [github.com/clubby789] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Bytes to Long Operation + */ +class BytesToLong extends Operation { + + /** + * LongToBytes constructor + */ + constructor() { + super(); + + this.name = "Bytes to Long"; + this.module = "Default"; + this.description = "Converts an array of bytes to a long integer.

e.g. Hello becomes 310939249775"; + this.inputType = "string"; + this.outputType = "string"; + } + + /** + * @param {string} input + * @returns {string} + */ + run(input, args) { + const bytes = []; + let charCode; + + for (let i = 0; i < input.length; ++i) { + charCode = input.charCodeAt(i); + bytes.unshift(charCode & 0xFF); + } + + let value = 0n; + for (let i = bytes.length - 1; i >= 0; i--) { + value = (value * 256n) + BigInt(bytes[i]); + } + + return value.toString(); + } + +} + +export default BytesToLong; diff --git a/src/core/operations/LongToBytes.mjs b/src/core/operations/LongToBytes.mjs new file mode 100644 index 000000000..5e9375e69 --- /dev/null +++ b/src/core/operations/LongToBytes.mjs @@ -0,0 +1,50 @@ +/** + * @author clubby789 [github.com/clubby789] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Long to Bytes Operation + */ +class LongToBytes extends Operation { + + /** + * LongToBytes constructor + */ + constructor() { + super(); + + this.name = "Long to Bytes"; + this.module = "Default"; + this.description = "Converts a long integer to an array of bytes.

e.g. 310939249775 becomes Hello"; + this.inputType = "string"; + this.outputType = "byteArray"; + this.checks = [ + { + pattern: "^[0-9]*$" + } + ]; + } + + /** + * @param {string} input + * @returns {byteArray} + */ + run(input, args) { + const byteArray = []; + let long = BigInt(input.replace(/[^\d]/g, "")); + for (let index = 0; long > 0n; index ++) { + const byte = long & 0xffn; + byteArray.unshift(Number(byte)); + long = (long - byte) / 256n ; + } + + return byteArray; + } + +} + +export default LongToBytes; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 40ce7a2ee..4cb0fb72e 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -33,6 +33,7 @@ import "./tests/BLAKE2s.mjs"; import "./tests/Bombe.mjs"; import "./tests/BSON.mjs"; import "./tests/ByteRepr.mjs"; +import "./tests/BytesLong.mjs"; import "./tests/CaesarBoxCipher.mjs"; import "./tests/CaretMdecode.mjs"; import "./tests/CartesianProduct.mjs"; diff --git a/tests/operations/tests/BytesLong.mjs b/tests/operations/tests/BytesLong.mjs new file mode 100644 index 000000000..b3bb500ed --- /dev/null +++ b/tests/operations/tests/BytesLong.mjs @@ -0,0 +1,34 @@ +/** + * BytesToLong/LongToBytes tests + * + * @author clubby789 [github.com/clubby789] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Bytes to Long", + input: "This is a testing string!", + expectedOutput: "529836718428447222471796396193323181240742300695594145834785", + recipeConfig: [ + { + op: "Bytes to Long", + args: [] + } + ], + }, + { + name: "Long to Bytes", + input: "529836718428447222471796396193323181240742300695594145834785", + expectedOutput: "This is a testing string!", + recipeConfig: [ + { + op: "Long to Bytes", + args: [] + } + ], + } +]);