moduleData.Digest.Murmur3(Hash,asByteString,hash)whereimportControl.MonadimportData.BitsimportData.ByteString(ByteString)importqualifiedData.ByteStringasBSimportData.WorddataHash=HashWord64Word64deriving(Eq,Ord)newtypeIdentitya=MakeIdentity{identityAction::a}instanceMonadIdentitywherereturna=MakeIdentitya(>>=)xf=f$identityActionxasByteString::Hash->ByteStringasByteString(Hashh1h2)=BS.pack[fromIntegral$shiftRh10.&.0xFF,fromIntegral$shiftRh18.&.0xFF,fromIntegral$shiftRh116.&.0xFF,fromIntegral$shiftRh124.&.0xFF,fromIntegral$shiftRh132.&.0xFF,fromIntegral$shiftRh140.&.0xFF,fromIntegral$shiftRh148.&.0xFF,fromIntegral$shiftRh156.&.0xFF,fromIntegral$shiftRh20.&.0xFF,fromIntegral$shiftRh28.&.0xFF,fromIntegral$shiftRh216.&.0xFF,fromIntegral$shiftRh224.&.0xFF,fromIntegral$shiftRh232.&.0xFF,fromIntegral$shiftRh240.&.0xFF,fromIntegral$shiftRh248.&.0xFF,fromIntegral$shiftRh256.&.0xFF]hash::ByteString->Hashhashinput=identityAction$doletc1=0x87c37b91114253d5letc2=0x4cf5ad432745937fseed=0totalLength=fromIntegral$BS.lengthinputletstep::Word64->Word64->Word64->Word64->Identity(Word64,Word64)steph1h2k1k2=do-- First linek1<-return$k1*c1k1<-return$rotateLk131k1<-return$k1*c2h1<-return$xorh1k1-- Second lineh1<-return$rotateLh127h1<-return$h1+h2h1<-return$h1*5+0x52dce729-- Third linek2<-return$k2*c2k2<-return$rotateLk233k2<-return$k2*c1h2<-return$xorh2k2-- Fourth lineh2<-return$rotateLh231h2<-return$h2+h1h2<-return$h2*5+0x38495ab5return(h1,h2)finish::Word64->Word64->Word64->Word64->IdentityHashfinishh1h2k1k2=do-- First linek1<-return$k1*c1k1<-return$rotateLk131k1<-return$k1*c2h1<-return$xorh1k1-- Third linek2<-return$k2*c2k2<-return$rotateLk233k2<-return$k2*c1h2<-return$xorh2k2-- Finalizationh1<-return$xorh1totalLengthh2<-return$xorh2totalLengthh1<-mixh1h2<-mixh2h1<-return$h1+h2h2<-return$h2+h1return$Hashh1h2mix::Word64->IdentityWord64mixk=dok<-return$xork(shiftRk33)k<-return$k*0xff51afd7ed558ccdk<-return$xork(shiftRk33)k<-return$k*0xc4ceb9fe1a85ec53k<-return$xork(shiftRk33)returnkloop::Word64->Word64->ByteString->IdentityHashlooph1h2input=do(k1,input)<-takeWord64input(k2,input)<-takeWord64inputifBS.nullinputthenfinishh1h2k1k2elsedo(h1,h2)<-steph1h2k1k2looph1h2inputtakeWord64::ByteString->Identity(Word64,ByteString)takeWord64input=dolet(front,rest)=BS.splitAt8inputword<-foldM(\sum(byte,offset)->doreturn$sum+(shiftL(fromIntegralbyte)offset))0(zip(BS.unpackfront)[0,8..56])return(word,rest)loopseedseedinput