truncatedHarmonic: number,
}
+/**
+* Checks if value is a string representing an N-byte hexadecimal number.
+*
+* @param {unknown} value - Value to check.
+* @param {(number|null)} byteLength - Number of bytes the string should represent, or 'null' for any number greater than zero.
+* @returns True if value is a 2N-character hexadecimal string, else false.
+*/
+export function isHexN (value: unknown, byteLength: number | null): value is string {
+ if (typeof value !== 'string') return false
+ const v = value.replace(/^0[Xx]/, '')
+ const length = byteLength === null ? '+' : `{${2 * byteLength}}`
+ const r = new RegExp(`^[A-Fa-f\\d]${length}\$`)
+ return r.test(v)
+}
+
+/**
+* Checks if value is a string representing an 8-byte hexadecimal number.
+*
+* @param {unknown} value - Value to check.
+* @returns True if value is a 16-character hexadecimal string, else false.
+*/
+export function isHex8 (value: unknown): value is string {
+ return isHexN(value, 8)
+}
+
+/**
+* Checks if value is a string representing a 32-byte hexadecimal number.
+*
+* @param {unknown} value - Value to check.
+* @returns True if value is a 64-character hex string, else false.
+*/
+export function isHex32 (value: unknown): value is string {
+ return isHexN(value, 32)
+}
+
+/**
+* Computes various types of averages for a set of numbers.
+*
+* @param {number[]} times - List of numbers, often timing durations.
+* @returns Object with averaged values for the specified list.
+*/
export function stats (times: number[]): Averages | null {
if (times == null || times.length === 0) return null