From 331370240abdcff58abac6433a1a5fad0198679c Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Fri, 10 May 2024 19:20:52 +0100 Subject: [PATCH] feat: add xor compare (#89) To allow sorting arrays of xor values, add an xor compare function that compares the relative distance of two xor arrays. --- README.md | 20 ++++++++++++++++++++ package.json | 4 ++++ src/index.ts | 20 ++++++++++++++++++++ src/xor-compare.ts | 20 ++++++++++++++++++++ src/xor.ts | 2 +- test/xor-compare.spec.ts | 10 ++++++++++ 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/xor-compare.ts create mode 100644 test/xor-compare.spec.ts diff --git a/README.md b/README.md index ce96f84..3f41714 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,26 @@ import { xor } from 'uint8arrays/xor' console.info(xor(Uint8Array.from([1, 0]), Uint8Array.from([0, 1]))) // Uint8Array[1, 1] ``` +## xorCompare(a, b) + +Compares the distances between two xor `Uint8Array`s. + +### Example + +```ts +import { xor } from 'uint8arrays/xor' +import { xorCompare } from 'uint8arrays/xor-compare' + +const target = Uint8Array.from([1, 1]) +const val1 = Uint8Array.from([1, 0]) +const xor1 = xor(target, val1) + +const val2 = Uint8Array.from([0, 1]) +const xor2 = xor(target, val2) + +console.info(xorCompare(xor1, xor2)) // -1 or 0 or 1 +``` + # Install ```console diff --git a/package.json b/package.json index 3c0de39..02e8544 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,10 @@ "./xor": { "types": "./dist/src/xor.d.ts", "import": "./dist/src/xor.js" + }, + "./xor-compare": { + "types": "./dist/src/xor-compare.d.ts", + "import": "./dist/src/xor-compare.js" } }, "imports": { diff --git a/src/index.ts b/src/index.ts index efdb141..329824b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -141,6 +141,26 @@ * * console.info(xor(Uint8Array.from([1, 0]), Uint8Array.from([0, 1]))) // Uint8Array[1, 1] * ``` + * + * ## xorCompare(a, b) + * + * Compares the distances between two xor `Uint8Array`s. + * + * ### Example + * + * ```ts + * import { xor } from 'uint8arrays/xor' + * import { xorCompare } from 'uint8arrays/xor-compare' + * + * const target = Uint8Array.from([1, 1]) + * const val1 = Uint8Array.from([1, 0]) + * const xor1 = xor(target, val1) + * + * const val2 = Uint8Array.from([0, 1]) + * const xor2 = xor(target, val2) + * + * console.info(xorCompare(xor1, xor2)) // -1 or 0 or 1 + * ``` */ import { equals } from './equals.js' diff --git a/src/xor-compare.ts b/src/xor-compare.ts new file mode 100644 index 0000000..f2fa64d --- /dev/null +++ b/src/xor-compare.ts @@ -0,0 +1,20 @@ +/** + * Compares two Uint8Arrays representing two xor distances. Returns `-1` if `a` + * is a lower distance, `1` if `b` is a lower distance or `0` if the distances + * are equal. + */ +export function xorCompare (a: Uint8Array, b: Uint8Array): -1 | 0 | 1 { + if (a.byteLength !== b.byteLength) { + throw new Error('Inputs should have the same length') + } + + for (let i = 0; i < a.byteLength; i++) { + if (a[i] === b[i]) { + continue + } + + return a[i] < b[i] ? -1 : 1 + } + + return 0 +} diff --git a/src/xor.ts b/src/xor.ts index d4f9819..9743ebd 100644 --- a/src/xor.ts +++ b/src/xor.ts @@ -2,7 +2,7 @@ import { allocUnsafe } from '#alloc' import { asUint8Array } from '#util/as-uint8array' /** - * Returns the xor distance between two arrays + * Returns the xor distance between two Uint8Arrays */ export function xor (a: Uint8Array, b: Uint8Array): Uint8Array { if (a.length !== b.length) { diff --git a/test/xor-compare.spec.ts b/test/xor-compare.spec.ts new file mode 100644 index 0000000..a5e7b6d --- /dev/null +++ b/test/xor-compare.spec.ts @@ -0,0 +1,10 @@ +import { expect } from 'aegir/chai' +import { xorCompare } from '../src/xor-compare.js' + +describe('xor-compare', () => { + it('compare', () => { + expect(xorCompare(Uint8Array.from([0, 0]), Uint8Array.from([0, 1]))).to.equal(-1) + expect(xorCompare(Uint8Array.from([0, 1]), Uint8Array.from([0, 1]))).to.equal(0) + expect(xorCompare(Uint8Array.from([1, 1]), Uint8Array.from([0, 1]))).to.equal(1) + }) +})