on master help sign in
Merge pull request #1586 from Helkafen/hash

Data.Hash module

commitb65d2c4c195a7e7aea0846c4538fec7acabf650e authorDavid Christiansen <david@davidchristiansen.dk> dateThu 9 Oct 2014, 21:37 (12 years ago) parent8ad21248430f90
7 files changed+120−2
idris.cabal+3 libs/base/Data/Hash.idr+85 libs/base/base.ipkg+1−1 test/Makefile+1−1 test/basic011/basic011.idr+16 test/basic011/expected+10 test/basic011/run+4
idris.cabal+3
@@ -302,6 +302,9 @@ Extra-source-files:
302302 test/basic010/run
303303 test/basic010/*.idr
304304 test/basic010/expected
305+ test/basic011/run
306+ test/basic011/*.idr
307+ test/basic011/expected
305308
306309 test/buffer001-disabled/*.idr
307310 test/buffer001-disabled/run
libs/base/Data/Hash.idrnew file+85
@@ -0,0 +1,85 @@
1+module Data.Hash
2+
3+%access public
4+%default total
5+
6+{- A general purpose Hashing library (not cryptographic)
7+
8+ The core hash is djb2, which is very fast but does not have the best distribution
9+ Source: http://www.cse.yorku.ca/~oz/hash.html
10+
11+ The salted version and the magic salt are copied from Haskell's bloomfilter library
12+ Source: https://hackage.haskell.org/package/bloomfilter-2.0.0.0/docs/src/Data-BloomFilter-Hash.html#Hashable
13+-}
14+
15+||| A type that can be hashed
16+class Hashable a where
17+ saltedHash64 : a -> Bits64 -> Bits64 -- value to hash, salt, hash
18+
19+||| Computes a non cryptographic hash
20+hash : Hashable a => a -> Bits64
21+hash x = saltedHash64 x 0x16fc397cf62f64d3
22+
23+||| Given a user provided salt, computes a non cryptographic hash.
24+||| This version is meant to mitigate hash-flooding DoS attacks.
25+saltedHash : Hashable a => Bits64 -> a -> Bits64
26+saltedHash salt x = saltedHash64 x salt
27+
28+
29+||| Nth byte of a Bits64
30+private
31+byte : Bits64 -> Bits64 -> Bits64
32+byte n w = prim__lshrB64 (prim__andB64 mask w) offset
33+ where offset = 8*n
34+ mask = prim__shlB64 0xff (the Bits64 offset)
35+
36+||| Modulo of an integer, downsized to a Bits64
37+private
38+mod64 : Integer -> Bits64
39+mod64 i = assert_total $ prim__truncBigInt_B64 (abs i `mod` 0xffffffffffffffff)
40+
41+instance Hashable Bits64 where
42+ saltedHash64 w salt = foldr (\b,acc => (acc `prim__shlB64` 10) + acc + b)
43+ salt
44+ [byte (fromInteger n) w | n <- [7,6..0]] -- djb2 hash function. Not meant for crypto
45+
46+instance Hashable Integer where
47+ saltedHash64 i = saltedHash64 (mod64 i)
48+
49+instance Hashable () where
50+ saltedHash64 _ salt = salt
51+
52+instance Hashable Bool where
53+ saltedHash64 True = saltedHash64 (the Bits64 1)
54+ saltedHash64 False = saltedHash64 (the Bits64 0)
55+
56+instance Hashable Int where
57+ saltedHash64 w = saltedHash64 (prim__zextInt_B64 w)
58+
59+instance Hashable Char where
60+ saltedHash64 w = saltedHash64 (the Int (cast w))
61+
62+instance Hashable Bits8 where
63+ saltedHash64 w = saltedHash64 (prim__zextB8_B64 w)
64+
65+instance Hashable Bits16 where
66+ saltedHash64 w = saltedHash64 (prim__zextB16_B64 w)
67+
68+instance Hashable Bits32 where
69+ saltedHash64 w = saltedHash64 (prim__zextB32_B64 w)
70+
71+instance Hashable a => Hashable (Maybe a) where
72+ saltedHash64 Nothing salt = salt
73+ saltedHash64 (Just k) salt = saltedHash64 k salt
74+
75+instance (Hashable a, Hashable b) => Hashable (a, b) where
76+ saltedHash64 (a,b) salt = saltedHash64 b (saltedHash64 a salt)
77+
78+instance Hashable a => Hashable (List a) where
79+ saltedHash64 l salt = foldr (\c,acc => saltedHash64 c acc) salt l
80+
81+instance Hashable a => Hashable (Vect n a) where
82+ saltedHash64 l salt = foldr (\c,acc => saltedHash64 c acc) salt l
83+
84+instance Hashable String where
85+ saltedHash64 s = saltedHash64 (unpack s)
libs/base/base.ipkg+1−1
@@ -24,7 +24,7 @@ modules = System,
2424 Data.Vect, Data.HVect, Data.Vect.Quantifiers,
2525 Data.Floats, Data.Complex, Data.Heap, Data.Fun,
2626 Data.Rel, Data.Buffer, Data.Erased,
27− Data.List,
27+ Data.List, Data.Hash,
2828
2929 Control.Isomorphism, Control.Isomorphism.Primitives,
3030 Control.Monad.Identity,
test/Makefile+1−1
@@ -11,7 +11,7 @@ test_java:
1111 @perl ./runtest.pl without --codegen Java
1212
1313test_js:
14− @perl ./runtest.pl without sugar004 reg029 reg052 io001 dsl002 io003 effects001 effects002 buffer001 --codegen node
14+ @perl ./runtest.pl without sugar004 reg029 reg052 io001 dsl002 io003 effects001 effects002 buffer001 basic011 --codegen node
1515
1616test_llvm:
1717 @perl ./runtest.pl without primitives003 sugar004 io003 buffer001 --codegen llvm
test/basic011/basic011.idrnew file+16
@@ -0,0 +1,16 @@
1+module Main
2+
3+import Data.Hash
4+
5+main : IO ()
6+main = do print $ hash (the Bits8 3)
7+ print $ hash (the (List Bits8) [3])
8+ print $ hash "hello world"
9+ print $ hash 'a'
10+ print $ hash (the Bits8 3)
11+ print $ hash (the Bits16 3)
12+ print $ hash (the Bits32 3)
13+ print $ hash (the Bits64 3)
14+ print $ hash (the Int 3)
15+ print $ hash (the Integer 3)
16+
test/basic011/expectednew file+10
@@ -0,0 +1,10 @@
1+6EA049D797FA18D6
2+6EA049D797FA18D6
3+FDA01C93B78A192F
4+AD85270E93646134
5+6EA049D797FA18D6
6+6EA049D797FA18D6
7+6EA049D797FA18D6
8+6EA049D797FA18D6
9+6EA049D797FA18D6
10+6EA049D797FA18D6
test/basic011/runnew file+4
@@ -0,0 +1,4 @@
1+#!/usr/bin/env bash
2+idris $@ basic011.idr -o basic011
3+./basic011
4+rm -f basic011 *.ibc