{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoMonomorphismRestriction #-} module EZCouch.Base62 where import Prelude () import ClassyPrelude import qualified Data.List as List import Data.Vector ((!)) import Data.Bits chars = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] charsVector = asVector . fromList $ chars charsLength = fromIntegral $ length charsVector -- | Produces individual values for the whole range of ints including negatives. If you know that the value will allways be positive use `fromUnsigned64` instead. fromSigned64 = fromUnsigned64 . zzEncode64 fromUnsigned64 0 = charsVector ! 0 : [] fromUnsigned64 a = if a >= 0 then reverse . fromUnsigned64' $ a else error $ "EZCouch.Base62.fromUnsigned64: Negative value: " ++ show a where fromUnsigned64' 0 = [] fromUnsigned64' a = charsVector ! fromIntegral c : fromUnsigned64' b where b = div a charsLength c = mod a charsLength zzEncode64 :: Int64 -> Word64 zzEncode64 x = fromIntegral ((x `shiftL` 1) `xor` (x `shiftR` 63))