Skip to content

Commit 2957ce1

Browse files
committed
hash: add printAsBase16
1 parent 8cc6595 commit 2957ce1

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

hnix-store-core/src/System/Nix/Hash.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module System.Nix.Hash (
2020
, HNix.hash
2121
, HNix.hashLazy
2222

23+
, HNix.printAsBase16
2324
, HNix.printAsBase32
2425
) where
2526

hnix-store-core/src/System/Nix/Internal/Hash.hs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ digestText32 d = algoString (Proxy :: Proxy a) <> ":" <> printAsBase32 d
102102
digestText16 :: forall a. HashAlgoText a => Digest a -> T.Text
103103
digestText16 (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
107111
printAsBase32 :: 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
193212
digits32 :: V.Vector Char
194213
digits32 = V.fromList "0123456789abcdfghijklmnpqrsvwxyz"
195214

hnix-store-core/tests/Hash.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ spec_hash = do
3434
it "produces (base32 . sha256) of \"nix-output:foo\" the same as Nix does at the moment for placeholder \"foo\"" $
3535
shouldBe (printAsBase32 (hash @SHA256 "nix-output:foo"))
3636
"1x0ymrsy7yr7i9wdsqy9khmzc1yy7nvxw6rdp72yzn50285s67j5"
37-
37+
it "produces (base16 . md5) of \"Hello World\" the same as the thesis" $
38+
shouldBe (printAsBase16 (hash @MD5 "Hello World"))
39+
"b10a8db164e0754105b7a99be72e3fe5"
3840
it "produces (base32 . sha1) of \"Hello World\" the same as the thesis" $
3941
shouldBe (printAsBase32 (hash @SHA1 "Hello World"))
4042
"s23c9fs0v32pf6bhmcph5rbqsyl5ak8a"

0 commit comments

Comments
 (0)