module Data.ByteString.Base58.Internal where
import Data.Bits
import Data.ByteString ( ByteString )
import Data.String
import Data.Typeable ( Typeable )
import Data.Word
import GHC.Generics ( Generic )
import qualified Data.ByteString as BS
import qualified Data.List as L
newtype Alphabet =
Alphabet
{ Alphabet -> ByteString
unAlphabet :: ByteString
} deriving (Eq Alphabet
Eq Alphabet
-> (Alphabet -> Alphabet -> Ordering)
-> (Alphabet -> Alphabet -> Bool)
-> (Alphabet -> Alphabet -> Bool)
-> (Alphabet -> Alphabet -> Bool)
-> (Alphabet -> Alphabet -> Bool)
-> (Alphabet -> Alphabet -> Alphabet)
-> (Alphabet -> Alphabet -> Alphabet)
-> Ord Alphabet
Alphabet -> Alphabet -> Bool
Alphabet -> Alphabet -> Ordering
Alphabet -> Alphabet -> Alphabet
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Alphabet -> Alphabet -> Alphabet
$cmin :: Alphabet -> Alphabet -> Alphabet
max :: Alphabet -> Alphabet -> Alphabet
$cmax :: Alphabet -> Alphabet -> Alphabet
>= :: Alphabet -> Alphabet -> Bool
$c>= :: Alphabet -> Alphabet -> Bool
> :: Alphabet -> Alphabet -> Bool
$c> :: Alphabet -> Alphabet -> Bool
<= :: Alphabet -> Alphabet -> Bool
$c<= :: Alphabet -> Alphabet -> Bool
< :: Alphabet -> Alphabet -> Bool
$c< :: Alphabet -> Alphabet -> Bool
compare :: Alphabet -> Alphabet -> Ordering
$ccompare :: Alphabet -> Alphabet -> Ordering
$cp1Ord :: Eq Alphabet
Ord, Alphabet -> Alphabet -> Bool
(Alphabet -> Alphabet -> Bool)
-> (Alphabet -> Alphabet -> Bool) -> Eq Alphabet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Alphabet -> Alphabet -> Bool
$c/= :: Alphabet -> Alphabet -> Bool
== :: Alphabet -> Alphabet -> Bool
$c== :: Alphabet -> Alphabet -> Bool
Eq, Int -> Alphabet -> ShowS
[Alphabet] -> ShowS
Alphabet -> String
(Int -> Alphabet -> ShowS)
-> (Alphabet -> String) -> ([Alphabet] -> ShowS) -> Show Alphabet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Alphabet] -> ShowS
$cshowList :: [Alphabet] -> ShowS
show :: Alphabet -> String
$cshow :: Alphabet -> String
showsPrec :: Int -> Alphabet -> ShowS
$cshowsPrec :: Int -> Alphabet -> ShowS
Show, Typeable, (forall x. Alphabet -> Rep Alphabet x)
-> (forall x. Rep Alphabet x -> Alphabet) -> Generic Alphabet
forall x. Rep Alphabet x -> Alphabet
forall x. Alphabet -> Rep Alphabet x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Alphabet x -> Alphabet
$cfrom :: forall x. Alphabet -> Rep Alphabet x
Generic, String -> Alphabet
(String -> Alphabet) -> IsString Alphabet
forall a. (String -> a) -> IsString a
fromString :: String -> Alphabet
$cfromString :: String -> Alphabet
IsString)
bitcoinAlphabet :: Alphabet
bitcoinAlphabet :: Alphabet
bitcoinAlphabet =
Alphabet
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
rippleAlphabet :: Alphabet
rippleAlphabet :: Alphabet
rippleAlphabet =
Alphabet
"rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
flickrAlphabet :: Alphabet
flickrAlphabet :: Alphabet
flickrAlphabet =
Alphabet
"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
b58 :: Alphabet -> Int -> Word8
b58 :: Alphabet -> Int -> Word8
b58 Alphabet
a Int
i = ByteString -> Int -> Word8
BS.index (Alphabet -> ByteString
unAlphabet Alphabet
a) Int
i
b58' :: Alphabet -> Word8 -> Maybe Int
b58' :: Alphabet -> Word8 -> Maybe Int
b58' Alphabet
a Word8
w = Word8 -> ByteString -> Maybe Int
BS.elemIndex Word8
w (Alphabet -> ByteString
unAlphabet Alphabet
a)
bsToInteger :: ByteString -> Integer
bsToInteger :: ByteString -> Integer
bsToInteger = ((Integer -> Word8 -> Integer) -> Integer -> [Word8] -> Integer
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' Integer -> Word8 -> Integer
forall a. Integral a => Integer -> a -> Integer
f Integer
0) ([Word8] -> Integer)
-> (ByteString -> [Word8]) -> ByteString -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [Word8]
BS.unpack
where
f :: Integer -> a -> Integer
f Integer
n a
w = (a -> Integer
forall a. Integral a => a -> Integer
toInteger a
w) Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.|. Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
shiftL Integer
n Int
8
integerToBS :: Integer -> ByteString
integerToBS :: Integer -> ByteString
integerToBS Integer
0 = [Word8] -> ByteString
BS.pack [Word8
0]
integerToBS Integer
i
| Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 = [Word8] -> ByteString
BS.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
forall a b. (a -> b) -> a -> b
$ [Word8] -> [Word8]
forall a. [a] -> [a]
reverse ([Word8] -> [Word8]) -> [Word8] -> [Word8]
forall a b. (a -> b) -> a -> b
$ (Integer -> Maybe (Word8, Integer)) -> Integer -> [Word8]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
L.unfoldr Integer -> Maybe (Word8, Integer)
f Integer
i
| Bool
otherwise = String -> ByteString
forall a. HasCallStack => String -> a
error String
"integerToBS not defined for negative values"
where
f :: Integer -> Maybe (Word8, Integer)
f Integer
0 = Maybe (Word8, Integer)
forall a. Maybe a
Nothing
f Integer
x = (Word8, Integer) -> Maybe (Word8, Integer)
forall a. a -> Maybe a
Just ((Word8, Integer) -> Maybe (Word8, Integer))
-> (Word8, Integer) -> Maybe (Word8, Integer)
forall a b. (a -> b) -> a -> b
$ (Integer -> Word8
forall a. Num a => Integer -> a
fromInteger Integer
x :: Word8, Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)