2e: Insecure Hashing

++fnv

FNV scrambler

Hashes an atom with the 32-bit FNV non-cryptographic hash algorithm. Multiplies a by the prime number 16,777,619 and then takes the block of size 5 off the product's end, producing an atom.

Accepts

a is an atom.

Produces

An atom.

Source

    ++  fnv  |=(a=@ (end 5 1 (mul 16.777.619 a)))

Examples

    > (fnv 10.000)
    272.465.456

    > (fnv 10.001)
    289.243.075

    > (fnv 1)
    16.777.619

++mug

FNV-1a scrambler

Hashes a with the 31-bit nonzero FNV-1a non-cryptographic hash algorithm, producing an atom.

Accepts

a is a noun.

Produces

An atom.

Source

    ++  mug
      ~/  %mug
      |=  a=*
      ?^  a
        =+  b=[p=$(a -.a) q=$(a +.a)]
        |-  ^-  @
        =+  c=(fnv (mix p.b (fnv q.b)))
        =+  d=(mix (rsh 0 31 c) (end 0 31 c))
        ?.  =(0 d)  d
        $(q.b +(q.b))
      =+  b=2.166.136.261
      |-  ^-  @
      =+  c=b
      =+  [d=0 e=(met 3 a)]
      |-  ^-  @
      ?:  =(d e)
        =+  f=(mix (rsh 0 31 c) (end 0 31 c))
        ?.  =(0 f)  f
        ^$(b +(b))
      $(c (fnv (mix c (cut 3 [d 1] a))), d +(d))

Examples

    > (mug 10.000)
    178.152.889

    > (mug 10.001)
    714.838.017

    > (mug 1)
    67.918.732

    > (mug (some 10))
    1.872.403.737

    > (mug [1 2 3 4 5 ~])
    1.067.931.605

++muk

Standard MurmurHash3

Implementation of the 32-bit MurmurHash3 non-cryptographic hash algorithm. Takes a as the seed, b as the key length in blocks of size 3, and c as the key, producing an atom.

Accepts

a is an atom.

b is an atom.

c is an atom.

Produces

An atom.

Source

    ++  muk
      ~%  %muk  ..muk  ~
      =+  ~(. fe 5)
      |=  [syd=@ len=@ key=@]
      ?>  &((lte (met 5 syd) 1) (lte (met 0 len) 31))
      =/  pad      (sub len (met 3 key))
      =/  data     (weld (rip 3 key) (reap pad 0))
      =/  nblocks  (div len 4)                             ::  intentionally off-by-one
      =/  h1  syd
      =+  [c1=0xcc9e.2d51 c2=0x1b87.3593]
      =/  blocks  (rip 5 key)
      =/  i  nblocks
      =.  h1  =/  hi  h1  |-
        ?:  =(0 i)  hi                                     ::  negative array index
        =/  k1  (snag (sub nblocks i) blocks)
        =.  k1  (sit (mul k1 c1))
        =.  k1  (rol 0 15 k1)
        =.  k1  (sit (mul k1 c2))
        =.  hi  (mix hi k1)
        =.  hi  (rol 0 13 hi)
        =.  hi  (sum (sit (mul hi 5)) 0xe654.6b64)
        $(i (dec i))
      =/  tail  (slag (mul 4 nblocks) data)
      =/  k1    0
      =/  tlen  (dis len 3)
      =.  h1
        ?+  tlen  h1                                       ::  fallthrough switch
          $3  =.  k1  (mix k1 (lsh 0 16 (snag 2 tail)))
              =.  k1  (mix k1 (lsh 0 8 (snag 1 tail)))
              =.  k1  (mix k1 (snag 0 tail))
              =.  k1  (sit (mul k1 c1))
              =.  k1  (rol 0 15 k1)
              =.  k1  (sit (mul k1 c2))
              (mix h1 k1)
          $2  =.  k1  (mix k1 (lsh 0 8 (snag 1 tail)))
              =.  k1  (mix k1 (snag 0 tail))
              =.  k1  (sit (mul k1 c1))
              =.  k1  (rol 0 15 k1)
              =.  k1  (sit (mul k1 c2))
              (mix h1 k1)
          $1  =.  k1  (mix k1 (snag 0 tail))
              =.  k1  (sit (mul k1 c1))
              =.  k1  (rol 0 15 k1)
              =.  k1  (sit (mul k1 c2))
              (mix h1 k1)
        ==
      =.  h1  (mix h1 len)
      |^  (fmix32 h1)
      ++  fmix32
        |=  h=@
        =.  h  (mix h (rsh 0 16 h))
        =.  h  (sit (mul h 0x85eb.ca6b))
        =.  h  (mix h (rsh 0 13 h))
        =.  h  (sit (mul h 0xc2b2.ae35))
        =.  h  (mix h (rsh 0 16 h))
        h
      --

Examples

    > (muk 6 1 3)
    3.427.677.118

    > (muk 6 2 'jerry')
    ! exit

    > (muk 6 2 'je')
    3.602.081.716

    > (met 3 'jerry')
    5

    > (met 3 'je')
    2

    > (muk 6 5 'jerry')
    1.276.447.489

    > (muk 6 15 'jerry')
    2.881.503.571

    > =e (cut 3 [0 2] eny)                            :: `eny` is 512 bits of entropy (a random number).
    > e
    44.228

    > (muk e 11 10.000)
    246.077.549

++mum

31-bit MurmurHash3 scrambler

Hashes a with the 31-bit MurmurHash3 non-cryptographic hash algorithm, producing an atom.

Accepts

a is a noun.

Produces

An atom.

Source

    ++  mum
      ~/  %mum
      |=  a=*
      |^  (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
      ++  trim
        |=  key=@
        =+  syd=0xcafe.babe
        |-  ^-  @
        =+  haz=(muk syd (met 3 key) key)
        =+  ham=(mix (rsh 0 31 haz) (end 0 31 haz))
        ?.(=(0 ham) ham $(syd +(syd)))

Examples

    > (mum 10.000)
    795.713.195

    > (mum 10.001)
    420.521.697

    > (mum 'jerry')
    1.540.161.753

    > (mum 1)
    1.901.865.568

    > (mum (some 10))
    2.099.076.946

    > (mum [1 2 3 4 5 ~])
    1.719.833.228