murmur3 (empty) → 1.0.0
raw patch · 6 files changed
+208/−0 lines, 6 filesdep +HUnitdep +QuickCheckdep +basesetup-changed
Dependencies added: HUnit, QuickCheck, base, base16-bytestring, binary, bytestring, murmur3, test-framework, test-framework-hunit, test-framework-quickcheck2
Files
- Data/Hash/Murmur.hs +73/−0
- Setup.hs +2/−0
- UNLICENSE +24/−0
- murmur3.cabal +52/−0
- tests/Data/Hash/Murmur/Units.hs +48/−0
- tests/Main.hs +9/−0
+ Data/Hash/Murmur.hs view
@@ -0,0 +1,73 @@+module Data.Hash.Murmur (murmur3) where++import Control.Monad (replicateM )+import Data.Binary + ( Binary+ , Word32 + )+import Data.Binary.Get + ( Get+ , runGet+ , getWord32le+ )+import Data.Bits + ( shiftR+ , rotateL+ , xor+ )+import qualified Data.ByteString as BS + ( ByteString + , length + , drop+ , append+ , replicate+ )+import qualified Data.ByteString.Lazy as BL+ ( fromStrict )++-- | MurmurHash3 (x86_32). For more details, see+-- <http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp>+murmur3 :: Word32 -- ^ Seed value+ -> BS.ByteString -- ^ Strict bytestring data to hash+ -> Word32 -- ^ MurmurHash3 result+murmur3 nHashSeed bs = + h8+ where+ -- Block and tail sizes+ nBlocks = BS.length bs `div` 4+ nTail = BS.length bs `mod` 4+ -- Data objects+ blocks = runGet' (replicateM nBlocks getWord32le) bs+ bsTail = BS.drop (nBlocks*4) bs `BS.append` BS.replicate (4-nTail) 0+ -- Body+ h1 = foldl mix nHashSeed blocks+ -- Tail+ t1 = runGet' getWord32le bsTail+ t2 = t1 * c1+ t3 = t2 `rotateL` 15+ t4 = t3 * c2+ h2 = h1 `xor` t4+ -- Finalization+ h3 = h2 `xor` (fromIntegral $ BS.length bs)+ h4 = h3 `xor` (h3 `shiftR` 16) + h5 = h4 * 0x85ebca6b+ h6 = h5 `xor` (h5 `shiftR` 13)+ h7 = h6 * 0xc2b2ae35+ h8 = h7 `xor` (h7 `shiftR` 16)+ -- Mix function+ mix r1 k1 = r4+ where+ k2 = k1 * c1+ k3 = k2 `rotateL` 15+ k4 = k3 * c2+ r2 = r1 `xor` k4+ r3 = r2 `rotateL` 13+ r4 = r3*5 + 0xe6546b64+ -- Constants+ c1 = 0xcc9e2d51 + c2 = 0x1b873593 ++-- Strict version of @Data.Binary.runGet@+runGet' :: Binary a => Get a -> BS.ByteString -> a+runGet' m = (runGet m) . BL.fromStrict+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ UNLICENSE view
@@ -0,0 +1,24 @@+This is free and unencumbered software released into the public domain.++Anyone is free to copy, modify, publish, use, compile, sell, or+distribute this software, either in source code form or as a compiled+binary, for any purpose, commercial or non-commercial, and by any+means.++In jurisdictions that recognize copyright laws, the author or authors+of this software dedicate any and all copyright interest in the+software to the public domain. We make this dedication for the benefit+of the public at large and to the detriment of our heirs and+successors. We intend this dedication to be an overt act of+relinquishment in perpetuity of all present and future rights to this+software under copyright law.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+OTHER DEALINGS IN THE SOFTWARE.++For more information, please refer to <http://unlicense.org/>
+ murmur3.cabal view
@@ -0,0 +1,52 @@+name: murmur3+version: 1.0.0+synopsis: + Pure Haskell implementation of the MurmurHash3 x86_32 algorithm.+description:+ MurmurHash3 is a non-cryptogrpahic hash function suitable for general+ hash-based lookup. We provide the x86_32 version which closely follows + the following implementation:+ <https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp>+homepage: http://github.com/plaprade/murmur3+bug-reports: http://github.com/plaprade/murmur3/issues+stability: stable+license: PublicDomain+license-file: UNLICENSE+author: Philippe Laprade+maintainer: plaprade+hackage@gmail.com+category: Data, Hash, Murmur+build-type: Simple+cabal-version: >= 1.9.2++source-repository head+ type: git+ location: git://github.com/haskoin/murmur3.git++library+ exposed-modules: Data.Hash.Murmur++ build-depends: base >= 4.6 && < 5 + , bytestring >= 0.10 && < 0.11 + , binary >= 0.7 && < 0.8 ++ ghc-options: -Wall ++test-suite test-murmur3+ type: exitcode-stdio-1.0+ main-is: Main.hs++ other-modules: Data.Hash.Murmur.Units++ build-depends: base >= 4.6 && < 5 + , base16-bytestring >= 0.1 && < 1.2+ , bytestring >= 0.10 && < 0.11 + , murmur3+ , HUnit >= 1.2 && < 1.3+ , QuickCheck >= 2.6 && < 2.9+ , test-framework >= 0.8 && < 0.9 + , test-framework-quickcheck2 >= 0.3 && < 0.4 + , test-framework-hunit >= 0.3 && < 0.4 ++ ghc-options: -Wall + hs-source-dirs: tests+
+ tests/Data/Hash/Murmur/Units.hs view
@@ -0,0 +1,48 @@+module Data.Hash.Murmur.Units (tests) where++import Test.HUnit (assertBool, Assertion)+import Test.Framework (Test, testGroup)+import Test.Framework.Providers.HUnit (testCase)++import Data.Word (Word32)+import qualified Data.ByteString.Base16 as B16 (decode)+import qualified Data.ByteString.Char8 as C (pack)++import Data.Hash.Murmur (murmur3)++type TestVector = (Word32, Word32, String)++tests :: [Test]+tests =+ [ testGroup "MurmurHash3" + (map buildTest $ zip testVectors [0..])+ ]++buildTest :: (TestVector, Int) -> Test.Framework.Test+buildTest (v, i) =+ testCase ("MurmurHash3 test vector " ++ show i) $ assertTestVector v++assertTestVector :: TestVector -> Assertion+assertTestVector (expected, seed, str) =+ assertBool " > MurmurHash3 " $ result == expected+ where+ result = murmur3 seed (fst $ B16.decode $ C.pack str)++testVectors :: [TestVector]+testVectors =+ [ (0x00000000, 0x00000000, "")+ , (0x6a396f08, 0xFBA4C795, "")+ , (0x81f16f39, 0xffffffff, "")+ , (0x514e28b7, 0x00000000, "00")+ , (0xea3f0b17, 0xFBA4C795, "00")+ , (0xfd6cf10d, 0x00000000, "ff")+ , (0x16c6b7ab, 0x00000000, "0011")+ , (0x8eb51c3d, 0x00000000, "001122")+ , (0xb4471bf8, 0x00000000, "00112233")+ , (0xe2301fa8, 0x00000000, "0011223344")+ , (0xfc2e4a15, 0x00000000, "001122334455")+ , (0xb074502c, 0x00000000, "00112233445566")+ , (0x8034d2a0, 0x00000000, "0011223344556677")+ , (0xb4698def, 0x00000000, "001122334455667788")+ ]+
+ tests/Main.hs view
@@ -0,0 +1,9 @@+module Main where++import Test.Framework (defaultMain)++import qualified Data.Hash.Murmur.Units (tests)++main :: IO ()+main = defaultMain (Data.Hash.Murmur.Units.tests)+