summaryrefslogtreecommitdiff
path: root/compiler/utils/Encoding.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils/Encoding.hs')
-rw-r--r--compiler/utils/Encoding.hs51
1 files changed, 50 insertions, 1 deletions
diff --git a/compiler/utils/Encoding.hs b/compiler/utils/Encoding.hs
index c8dcea24a7..712de6ca82 100644
--- a/compiler/utils/Encoding.hs
+++ b/compiler/utils/Encoding.hs
@@ -25,11 +25,16 @@ module Encoding (
-- * Z-encoding
zEncodeString,
- zDecodeString
+ zDecodeString,
+
+ -- * Base62-encoding
+ toBase62,
+ toBase62Padded
) where
import Foreign
import Data.Char
+import qualified Data.Char as Char
import Numeric
import GHC.Exts
@@ -385,3 +390,47 @@ maybe_tuple _ = Nothing
count_commas :: Int -> String -> (Int, String)
count_commas n (',' : cs) = count_commas (n+1) cs
count_commas n cs = (n,cs)
+
+
+{-
+************************************************************************
+* *
+ Base 62
+* *
+************************************************************************
+
+Note [Base 62 encoding 128-bit integers]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Instead of base-62 encoding a single 128-bit integer
+(ceil(21.49) characters), we'll base-62 a pair of 64-bit integers
+(2 * ceil(10.75) characters). Luckily for us, it's the same number of
+characters!
+-}
+
+--------------------------------------------------------------------------
+-- Base 62
+
+-- The base-62 code is based off of 'locators'
+-- ((c) Operational Dynamics Consulting, BSD3 licensed)
+
+-- | Size of a 64-bit word when written as a base-62 string
+word64Base62Len :: Int
+word64Base62Len = 11
+
+-- | Converts a 64-bit word into a base-62 string
+toBase62Padded :: Word64 -> String
+toBase62Padded w = pad ++ str
+ where
+ pad = replicate len '0'
+ len = word64Base62Len - length str -- 11 == ceil(64 / lg 62)
+ str = toBase62 w
+
+toBase62 :: Word64 -> String
+toBase62 w = showIntAtBase 62 represent w ""
+ where
+ represent :: Int -> Char
+ represent x
+ | x < 10 = Char.chr (48 + x)
+ | x < 36 = Char.chr (65 + x - 10)
+ | x < 62 = Char.chr (97 + x - 36)
+ | otherwise = error "represent (base 62): impossible!"