module System.Nix.Hash.Truncation
( truncateInNixWay
) where
import Data.Word (Word8)
import Data.ByteString (ByteString)
import qualified Data.ByteString
import qualified Data.Bits
import qualified Data.Bool
import qualified Data.List
truncateInNixWay
:: Int -> ByteString -> ByteString
truncateInNixWay :: Int -> ByteString -> ByteString
truncateInNixWay Int
n ByteString
c =
[Word8] -> ByteString
Data.ByteString.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Int -> Word8) -> [Int] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word8
truncOutputByte [Int
0 .. Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]
where
truncOutputByte :: Int -> Word8
truncOutputByte :: Int -> Word8
truncOutputByte Int
i = (Word8 -> Int -> Word8) -> Word8 -> [Int] -> Word8
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
Data.List.foldl' (Int -> Word8 -> Int -> Word8
aux Int
i) Word8
0 [Int
0 .. ByteString -> Int
Data.ByteString.length ByteString
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
inputByte :: Int -> Word8
inputByte :: Int -> Word8
inputByte Int
j = HasCallStack => ByteString -> Int -> Word8
ByteString -> Int -> Word8
Data.ByteString.index ByteString
c Int
j
aux :: Int -> Word8 -> Int -> Word8
aux :: Int -> Word8 -> Int -> Word8
aux Int
i Word8
x Int
j =
(Word8 -> Word8) -> (Word8 -> Word8) -> Bool -> Word8 -> Word8
forall a. a -> a -> Bool -> a
Data.Bool.bool
Word8 -> Word8
forall a. a -> a
id
(Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`Data.Bits.xor` Int -> Word8
inputByte Int
j)
(Int
j Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
i)
Word8
x