hnix-store-core-0.1.0.0: src/System/Nix/Base32.hs
{-|
Description: Implementation of Nix's base32 encoding.
-}
module System.Nix.Base32 where
import qualified Data.ByteString as BS
import qualified Data.Text as T
import qualified Data.Vector as V
-- | Encode a 'BS.ByteString' in Nix's base32 encoding
encode :: BS.ByteString -> T.Text
encode c = T.pack $ concatMap char32 [nChar - 1, nChar - 2 .. 0]
where
digits32 = V.fromList "0123456789abcdfghijklmnpqrsvwxyz"
-- The base32 encoding is 8/5's as long as the base256 digest. This `+ 1`
-- `- 1` business is a bit odd, but has always been used in C++ since the
-- base32 truncation was added in was first added in
-- d58a11e019813902b6c4547ca61a127938b2cc20.
nChar = fromIntegral $ ((BS.length c * 8 - 1) `div` 5) + 1
char32 :: Integer -> [Char]
char32 i = [digits32 V.! digitInd]
where
byte j = BS.index c (fromIntegral j)
fromIntegral' :: Num b => Integer -> b
fromIntegral' = fromIntegral
digitInd = fromIntegral' $
sum [fromIntegral (byte j) * (256^j)
| j <- [0 .. BS.length c - 1]]
`div` (32^i)
`mod` 32