this repo has no description
1module KnotHash
2 ( knotHash
3 ) where
4
5import Data.List.Grouping (splitEvery)
6import Data.Bits (xor)
7import Data.Char
8import Numeric (showHex)
9
10knotHash :: String -> String
11knotHash = denseHash . sparseHash
12
13sparseHash :: String -> [Int]
14sparseHash str = go 1 0 0 [0..255] lengths
15 where lengths = (map ord str) ++ [17,31,73,47,23]
16 go :: Int -> Int -> Int -> [Int] -> [Int] -> [Int]
17 go 64 _ _ rope [] = rope
18 go r p s rope [] = go (r + 1) p s rope lengths
19 go r p s rope (l:ls) =
20 go r (mod (p + l + s) 256) (s + 1) (twistRope p l rope) ls
21
22denseHash :: [Int] -> String
23denseHash ints = concatMap getHex nums
24 where nums :: [Int]
25 nums = map (\g -> foldl1 xor g) $ splitEvery 16 ints
26
27getHex :: Int -> String
28getHex i = let h = showHex i ""
29 in if length h == 2 then h else "0" ++ h
30
31twistRope :: Int -> Int -> [Int] -> [Int]
32twistRope p l rope =
33 let frontEnd = (p + l) - 256
34 newSection = reverse . take l . drop p $ cycle rope
35 in (drop (l - frontEnd) newSection) ++ (drop frontEnd . take p $ rope) ++
36 (take (l - frontEnd) newSection) ++ (drop (p + l) rope)