{-# language ScopedTypeVariables #-}
{-# language DataKinds #-}
module System.Nix.Internal.Truncation
( truncateInNixWay
)
where
import qualified Data.ByteString as Bytes
truncateInNixWay
:: Int -> Bytes.ByteString -> Bytes.ByteString
truncateInNixWay :: Int -> ByteString -> ByteString
truncateInNixWay Int
n ByteString
c =
[Word8] -> ByteString
Bytes.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
forall a b. (a -> b) -> a -> b
$ (Int -> Word8) -> [Int] -> [Word8]
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 (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Int -> Word8 -> Int -> Word8
aux Int
i) Word8
0 [Int
0 .. ByteString -> Int
Bytes.length ByteString
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
inputByte :: Int -> Word8
inputByte :: Int -> Word8
inputByte Int
j = ByteString -> Int -> Word8
Bytes.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
bool
Word8 -> Word8
forall a. a -> a
id
(Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`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