@@ -102,6 +102,10 @@ digestText32 d = algoString (Proxy :: Proxy a) <> ":" <> printAsBase32 d
102102digestText16 :: forall a . HashAlgoText a => Digest a -> T. Text
103103digestText16 (Digest bs) = algoString (Proxy :: Proxy a ) <> " :" <> T. decodeUtf8 (Base16. encode bs)
104104
105+ -- | Convert any Digest to a base16-encoded string.
106+ printAsBase16 :: Digest a -> T. Text
107+ printAsBase16 (Digest bs) = printHashBytes16 bs
108+
105109-- | Convert any Digest to a base32-encoded string.
106110-- This is not used in producing store path hashes
107111printAsBase32 :: Digest a -> T. Text
@@ -144,6 +148,17 @@ newtype Digest (a :: HashAlgorithm) = Digest
144148-- hashWithSalt a (Digest bs) = DataHashable.hashWithSalt a bs
145149-- hashWithSalt = coerce . DataHash
146150
151+ -- | Internal function for encoding bytestrings into base16 according to
152+ -- nix's convention
153+ printHashBytes16 :: BS. ByteString -> T. Text
154+ printHashBytes16 c = T. pack $ concatMap char16 [0 .. (fromIntegral (BS. length c - 1 ))]
155+ where
156+ -- The base16 encoding is twice as long as the base256 digest
157+ char16 :: Integer -> [Char ]
158+ char16 i = [digits16 V. ! (fromIntegral (byte i) `div` 16 ),
159+ digits16 V. ! (fromIntegral (byte i) `mod` 16 )]
160+ where
161+ byte j = BS. index c (fromIntegral j)
147162
148163-- | Internal function for encoding bytestrings into base32 according to
149164-- nix's convention
@@ -190,6 +205,10 @@ truncateDigest (Digest c) = Digest $ BS.pack $ map truncOutputByte [0.. n-1]
190205 then xor x (inputByte $ fromIntegral j)
191206 else x
192207
208+ digits16 :: V. Vector Char
209+ digits16 = V. fromList " 0123456789abcdef"
210+
211+ -- omitted: E O U T
193212digits32 :: V. Vector Char
194213digits32 = V. fromList " 0123456789abcdfghijklmnpqrsvwxyz"
195214
0 commit comments