    -- | Implementation of base-62 encoding, which we use when computing hashes
    -- for fully instantiated unit ids.
    module Distribution.Utils.Base62 (hashToBase62) where

    import Data.Char (chr)
    import GHC.Fingerprint (Fingerprint (..), fingerprintString)
    import Numeric (showIntAtBase)

    -- | Hash a string using GHC's fingerprinting algorithm (a 128-bit
    -- MD5 hash) and then encode the resulting hash in base 62.
    hashToBase62 :: String -> String
    hashToBase62 :: String -> String
    hashToBase62 String
    s = Fingerprint -> String
    showFingerprint (Fingerprint -> String) -> Fingerprint -> String
    forall a b. (a -> b) -> a -> b
    $ String -> Fingerprint
    fingerprintString String
    s
      where
        showIntAtBase62 :: a -> String
    showIntAtBase62 a
    x = a -> (Int -> Char) -> a -> String -> String
    forall a. Integral a => a -> (Int -> Char) -> a -> String -> String
    showIntAtBase a
    62 Int -> Char
    representBase62 a
    x String
    ""
        representBase62 :: Int -> Char
    representBase62 Int
    x
          | Int
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    10 = Int -> Char
    chr (Int
    48 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    x)
          | Int
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    36 = Int -> Char
    chr (Int
    65 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    10)
          | Int
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    62 = Int -> Char
    chr (Int
    97 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    36)
          | Bool
    otherwise = Char
    '@'
        showFingerprint :: Fingerprint -> String
    showFingerprint (Fingerprint Word64
    a Word64
    b) = Word64 -> String
    forall {a}. Integral a => a -> String
    showIntAtBase62 Word64
    a String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word64 -> String
    forall {a}. Integral a => a -> String
    showIntAtBase62 Word64
    b