hashing

Hash tables and hash­ing ob­jects.

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Source:

Classes

DefaultHasher
HashMap
HashSet
UnorderedHasher

Interfaces

Hashable
Hasher

Methods

(inner) bytes2hex(buf, T) → {T}

Source:

Con­vert Uint8Ar­ray into a hex en­coded string.

const as­sert = re­quire('assert');
const { bytes2hex, hash } = re­quire('fer­rum');

// You can use this to de­rive a string value from hashes
as­sert.stric­tEqual(
  bytes2hex(hash({ foo: "Hello World" })),
  "8c363e9e1b­cab­de7");

// Which is use­ful be­cause now the === op­er­ator works prop­erly.
// (=== on Uint8Ar­ray com­pares by iden­tity, not by con­tent)
as­sert(hash(1) !== hash(1));
as­sert(bytes2hex(hash(1)) === bytes2hex(hash(1)));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
buf Uint8Array

The buf­fer to con­vert into hex

T function

The tar­get type

Returns:
Type
T

(inner) defaultBuildHasher() → {function}

Source:

This is really just a wrap­per for De­faultHasher.new() that needs to be in­voked twice. While it really does noth­ing of in­terest, it is provided so it can be used as a drop in re­place­ment for other build­Hasher con­struct­ors like ran­dom­Build­Hasher.

A Hasher is an ob­ject that im­ple­ments the Hasher in­ter­face (e.g. De­faultHasher). A build­Hasher is a nul­lary (zero para­meter func­tion) con­structor for a Hasher (e.g. De­faultHasher.new). A gen­Build­Hasher pro­duces a build­Hasher; this func­tion is a gen­Build­Hasher.

const as­sert = re­quire('assert');
const { hash­With, bytes2hex, de­fault­Build­Hasher, hash } = re­quire('fer­rum');

const h1 = hash({ foo: [1, 2] });
const h2 = hash­With({ foo: [1, 2] }, de­fault­Build­Hasher());
const h3 = de­fault­Build­Hasher()().up­date({ foo: [1, 2] }).di­gest();
as­sert.stric­tEqual(bytes2hex(h1), bytes2hex(h2));
as­sert.stric­tEqual(bytes2hex(h1), bytes2hex(h3));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Returns:

De­faultHasher.new

Type
function

(inner) hash(v) → {Uint8Array}

Source:

Cal­cu­lates the hash of the given value us­ing the de­fault hasher.

const as­sert = re­quire('assert')
const { hash, De­faultHasher, bytes2hex } = re­quire('fer­rum');

as­sert.stric­tEqual(
  bytes2hex(hash({ foo: [1, 2] })),
  bytes2hex(De­faultHasher.new().up­date({ foo: [1, 2] }).di­gest()));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hashDirectly() → {Uint8Array}

Source:

Con­vert ba­sic data types into byte se­quences.

The fol­low­ing seri­al­iz­a­tion rules are used:

  • Typed ar­rays into their little en­dian rep­res­ent­a­tion
  • Strings as UTF-8
  • As a single ele­ment Float64Ar­ray.
  • null as hex2­bytes('6218e­f48d321422­fa9b4416563903f05')
  • un­defined as hex2­bytes('0308394d20384acda38432c81d0654ed')
  • true as hex2­bytes('24817a77c9374571a9469a92­faed50b3')
  • false as hex2­bytes('74070422b­b654cf788c9­be­f90900a8f2'),

Other types cur­rently res­ult in an er­ror, but fur­ther types may be ad­ded in the fu­ture.

const as­sert = re­quire('assert');
const { hash, hash­Dir­ectly, bytes2hex, hex2­bytes } = re­quire('fer­rum');

const h1 = hash(hash­Dir­ectly(0));
const h2 = hash(hex2­bytes('0000000000000000'));
as­sert.stric­tEqual(bytes2hex(h1), bytes2hex(h2));

// Without hash­Dir­ectly num­bers are hashed in a more com­plex way
// that in­volves the use of type tag­ging.
const h3 = hash(0);
as­sert.not­Stric­tEqual(bytes2hex(h1), bytes2hex(h3));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Type Description
Returns:
Type
Uint8Array

(inner) hashmap(seq) → {HashMap}

Source:

Con­structs a hashmap from a se­quence

const as­sert = re­quire('assert');
const { hashmap } = re­quire('fer­rum');

const hm = hashmap([[{}, 42], [[], 23]]);
as­sert.stric­tEqual(hm.size, 2);
as­sert.stric­tEqual(hm.get({}), 42);

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
seq Sequence
Returns:
Type
HashMap

(inner) hashSeq(v) → {Uint8Array}

Source:

Hash mul­tiple val­ues us­ing the de­fault hasher. This cor­res­ponds to re­peated .up­date() calls.

const as­sert = re­quire('assert');
const { hash­Seq, bytes2hex, De­faultHasher } = re­quire('fer­rum');

as­sert.stric­tEqual(
  bytes2hex(hash­Seq([{}, [1,2,3]])),
  bytes2hex(De­faultHasher.new().up­date({}).up­date([1,2,3]).di­gest()));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Se­quence of any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hashSeqWith(v) → {Uint8Array}

Source:

Hash mul­tiple val­ues us­ing a cus­tom build­Hasher. This cor­res­ponds to re­peated .up­date() calls.

const as­sert = re­quire('assert')
const { hash­SeqWith, bytes2hex, ran­dom­Build­Hasher } = re­quire('fer­rum');

const bh = ran­dom­Build­Hasher();
as­sert.stric­tEqual(
  bytes2hex(hash­SeqWith([{}, [1,2,3]], bh)),
  bytes2hex(bh().up­date({}).up­date([1,2,3]).di­gest()));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Se­quence of any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hashset(seq) → {HashMap}

Source:

Con­structs a hash­set from a se­quence

const as­sert = re­quire('assert');
const { hash­set } = re­quire('fer­rum');

const hm = hash­set([32, {}, 42, []]);
as­sert.stric­tEqual(hm.size, 4);
as­sert(hm.has([]));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
seq Sequence
Returns:
Type
HashMap

(inner) hashUnordered(v) → {Uint8Array}

Source:

Hash mul­tiple val­ues us­ing Un­ordered­Hasher+De­faultHasher. This cor­res­ponds to re­peated .up­date() call; the or­der does­n't mat­ter.

const as­sert = re­quire('assert');
const {
  hash­SeqWith, hashUn­ordered, bytes2hex, un­ordered­Build­Hasher,
  de­fault­Build­Hasher,
} = re­quire('fer­rum');

as­sert.stric­tEqual(
  bytes2hex(hashUn­ordered([{}, [1,2,3]])),
  bytes2hex(hash­SeqWith([[1,2,3], {}],
    un­ordered­Build­Hasher(de­fault­Build­Hasher()))));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Se­quence of any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hashUnorderedWith(v) → {Uint8Array}

Source:

Hash mul­tiple val­ues us­ing Un­ordered­Hasher and a cus­tom build­Hasher. This cor­res­ponds to re­peated .up­date() call; the or­der does­n't mat­ter.

const as­sert = re­quire('assert')
const {
  hash­SeqWith, bytes2hex, ran­dom­Build­Hasher,
  un­ordered­Build­Hasher, hashUn­ordered­With,
} = re­quire('fer­rum');

const bh = ran­dom­Build­Hasher();
as­sert.stric­tEqual(
  bytes2hex(hashUn­ordered­With([{}, [1,2,3]], bh)),
  bytes2hex(hash­SeqWith([[1,2,3], {}],
    un­ordered­Build­Hasher(bh))));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Se­quence of any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hashWith(v) → {Uint8Array}

Source:

Cal­cu­lates the hash of the given value us­ing some cus­tom build hasher.

const as­sert = re­quire('assert')
const { hash­With, bytes2hex, ran­dom­Build­Hasher } = re­quire('fer­rum');

const bh = ran­dom­Build­Hasher();
const h = hash­With(bh); // hash­With is curry­able
as­sert.stric­tEqual(
  bytes2hex(h({ foo: [1, 2] })),
  bytes2hex(bh().up­date({ foo: [1, 2] }).di­gest()));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
v *

Any­thing that im­ple­ments Hash­able

Returns:
Type
Uint8Array

(inner) hex2bytes(buf, T) → {T}

Source:

Con­vert a hex en­coded string to an Uint8Ar­ray.

const { hex2­bytes, as­ser­tEquals } = re­quire('fer­rum');

as­ser­tEquals(
  hex2­bytes("ff00ff00"),
  new Uint8Ar­ray([0xff, 0x00, 0xff, 0x00]));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Parameters:
Name Type Description
buf Uint8Array

The buf­fer to con­vert into hex

T function

The tar­get type

Returns:
Type
T

(inner) randomBuildHasher() → {function}

Source:

Cre­ate a new build­Hasher us­ing a ran­dom seed.

This is mostly use­ful as a mit­ig­a­tion against at­tacks like hash­dos. Us­ing this is usu­ally a bet­ter choice of de­fault build­Hasher than de­fault­Build­Hasher.

A Hasher is an ob­ject that im­ple­ments the Hasher in­ter­face (e.g. De­faultHasher). A build­Hasher is a nul­lary (zero para­meter func­tion) con­structor for a Hasher (e.g. De­faultHasher.new). A gen­Build­Hasher pro­duces a build­Hasher; this func­tion is a gen­Build­Hasher.

const as­sert = re­quire('assert')
const { hash­With, bytes2hex, ran­dom­Build­Hasher, hash } = re­quire('fer­rum');

const r1 = ran­dom­Build­Hasher();
const r2 = ran­dom­Build­Hasher();
as­sert.stric­tEqual(
  bytes2hex(hash­With({ foo: 1 }, r1)),
  bytes2hex(hash­With({ foo: 1 }, r1)));
as­sert.not­Stric­tEqual(
  bytes2hex(hash­With({ foo: 1 }, r1)),
  bytes2hex(hash­With({ foo: 1 }, r2)));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Returns:

De­faultHasher.new

Type
function

(inner) seededBuildHasher() → {function}

Source:

Cre­ate a new build­Hasher us­ing a seed.

A Hasher is an ob­ject that im­ple­ments the Hasher in­ter­face (e.g. De­faultHasher). A build­Hasher is a nul­lary (zero para­meter func­tion) con­structor for a Hasher (e.g. De­faultHasher.new). A gen­Build­Hasher pro­duces a build­Hasher; this func­tion is a gen­Build­Hasher.

const as­sert = re­quire('assert')
const { hash­With, bytes2hex, seeded­Build­Hasher, hash } = re­quire('fer­rum');

const s1 = seeded­Build­Hasher(new Uint8Ar­ray([0, 0, 0, 0, 0, 0, 0, 0]));
const s2 = seeded­Build­Hasher(new Uint8Ar­ray([0, 0, 0, 0, 0, 0, 0, 1]));
as­sert.stric­tEqual(
  bytes2hex(hash­With({ foo: 1 }, s1)),
  bytes2hex(hash­With({ foo: 1 }, s1)));
as­sert.not­Stric­tEqual(
  bytes2hex(hash­With({ foo: 1 }, s1)),
  bytes2hex(hash­With({ foo: 1 }, s2)));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Returns:

De­faultHasher.new

Type
function

(inner) unorderedBuildHasher() → {function}

Source:

Build­Hasher for Un­ordered­Hasher.

A Hasher is an ob­ject that im­ple­ments the Hasher in­ter­face (e.g. De­faultHasher). A build­Hasher is a nul­lary (zero para­meter func­tion) con­structor for a Hasher (e.g. De­faultHasher.new). A gen­Build­Hasher pro­duces a build­Hasher; this func­tion is a gen­Build­Hasher.

const as­sert = re­quire('assert')
const {
  hash­SeqWith, bytes2hex, ran­dom­Build­Hasher, un­ordered­Build­Hasher, hash
} = re­quire('fer­rum');

const r1 = ran­dom­Build­Hasher();
as­sert.stric­tEqual(
  bytes2hex(hash­SeqWith([23, {}], un­ordered­Build­Hasher(r1))),
  bytes2hex(hash­SeqWith([{}, 23], un­ordered­Build­Hasher(r1))));

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion
Returns:

De­faultHasher.new

Type
function