packages feed

base58-bytestring 0.0.3 → 0.1.0

raw patch · 4 files changed

+123/−55 lines, 4 filesdep +criterionPVP ok

version bump matches the API change (PVP)

Dependencies added: criterion

API changes (from Hackage documentation)

- Data.ByteString.Base58: instance Constructor C1_0Alphabet
- Data.ByteString.Base58: instance Datatype D1Alphabet
- Data.ByteString.Base58: instance Eq Alphabet
- Data.ByteString.Base58: instance Generic Alphabet
- Data.ByteString.Base58: instance IsString Alphabet
- Data.ByteString.Base58: instance Ord Alphabet
- Data.ByteString.Base58: instance Selector S1_0_0Alphabet
- Data.ByteString.Base58: instance Show Alphabet
- Data.ByteString.Base58: instance Typeable Alphabet
+ Data.ByteString.Base58.Internal: Alphabet :: ByteString -> Alphabet
+ Data.ByteString.Base58.Internal: b58 :: Alphabet -> Int -> Word8
+ Data.ByteString.Base58.Internal: b58' :: Alphabet -> Word8 -> Maybe Int
+ Data.ByteString.Base58.Internal: bitcoinAlphabet :: Alphabet
+ Data.ByteString.Base58.Internal: bsToInteger :: ByteString -> Integer
+ Data.ByteString.Base58.Internal: flickrAlphabet :: Alphabet
+ Data.ByteString.Base58.Internal: instance Constructor C1_0Alphabet
+ Data.ByteString.Base58.Internal: instance Datatype D1Alphabet
+ Data.ByteString.Base58.Internal: instance Eq Alphabet
+ Data.ByteString.Base58.Internal: instance Generic Alphabet
+ Data.ByteString.Base58.Internal: instance IsString Alphabet
+ Data.ByteString.Base58.Internal: instance Ord Alphabet
+ Data.ByteString.Base58.Internal: instance Selector S1_0_0Alphabet
+ Data.ByteString.Base58.Internal: instance Show Alphabet
+ Data.ByteString.Base58.Internal: instance Typeable Alphabet
+ Data.ByteString.Base58.Internal: integerToBS :: Integer -> ByteString
+ Data.ByteString.Base58.Internal: newtype Alphabet
+ Data.ByteString.Base58.Internal: rippleAlphabet :: Alphabet
+ Data.ByteString.Base58.Internal: unAlphabet :: Alphabet -> ByteString

Files

base58-bytestring.cabal view
@@ -1,5 +1,5 @@ name:                base58-bytestring-version:             0.0.3+version:             0.1.0 synopsis:            Implementation of BASE58 transcoding for ByteStrings  description: Implementation of BASE58 transcoding copy-pasted from@@ -20,6 +20,7 @@  library   exposed-modules: Data.ByteString.Base58+                 , Data.ByteString.Base58.Internal    default-extensions: OverloadedStrings                     , DeriveDataTypeable@@ -40,6 +41,7 @@    hs-source-dirs:  test   ghc-options:     -Wall -rtsopts -threaded+  default-language:    Haskell2010    build-depends:       base >=4.6 && < 5                      , base58-bytestring@@ -48,3 +50,19 @@                      , quickcheck-instances                      , tasty                      , tasty-quickcheck+++benchmark bench+  type:    exitcode-stdio-1.0+  main-is: Main.hs++  default-extensions: OverloadedStrings++  hs-source-dirs:  bench+  ghc-options:     -Wall -rtsopts -threaded+  default-language:    Haskell2010++  build-depends:       base >=4.6 && < 5+                     , base58-bytestring+                     , bytestring+                     , criterion
+ bench/Main.hs view
@@ -0,0 +1,41 @@+module Main where++import Data.Word+import Criterion.Main+import Data.ByteString ( ByteString )+import Data.ByteString.Base58++import qualified Data.ByteString as BS++symChars :: [Word8]+symChars = cycle+           $ BS.unpack+           $ unAlphabet bitcoinAlphabet++symN :: Int -> ByteString+symN n = BS.pack+         $ take n+         $ symChars++nameVal :: [(String, Int)]+nameVal = [ ("10 bytes", 10)+          , ("42 bytes", 100)+          , ("100 bytes", 1000) ]++main :: IO ()+main = defaultMain+       [ bgroup "encodeBase58I"+         [ bench "approx 10 bytes (1e24)" $  nf (encodeBase58I bitcoinAlphabet) 1000000000000000000000000+         , bench "approx 42 bytes (1e100)" $ nf (encodeBase58I bitcoinAlphabet) 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+         , bench "approx 100 bytes (1e240)" $ nf (encodeBase58I bitcoinAlphabet) 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+         ]++       , bgroup "decodeBase58I"+         $ map (\(name, val) -> bench name $ nf (decodeBase58I bitcoinAlphabet) $ symN val) nameVal++       , bgroup "encodeBase58"+         $ map (\(name, val) -> bench name $ nf (encodeBase58 bitcoinAlphabet) $ symN val) nameVal++       , bgroup "decodeBase58"+         $ map (\(name, val) -> bench name $ nf (decodeBase58 bitcoinAlphabet) $ symN val) nameVal+       ]
src/Data/ByteString/Base58.hs view
@@ -13,45 +13,16 @@        ) where  import Control.Applicative-import Data.Bits import Data.ByteString ( ByteString )+import Data.ByteString.Base58.Internal import Data.Char (chr, ord) import Data.Maybe-import Data.String-import Data.Typeable ( Typeable )-import Data.Word-import GHC.Generics ( Generic ) import Numeric  import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BC-import qualified Data.List as L -newtype Alphabet =-    Alphabet-    { unAlphabet  :: ByteString-    } deriving (Ord, Eq, Show, Typeable, Generic, IsString) -bitcoinAlphabet :: Alphabet-bitcoinAlphabet =-    "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"--rippleAlphabet :: Alphabet-rippleAlphabet =-    "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"--flickrAlphabet :: Alphabet-flickrAlphabet =-    "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"---- | Take 'i' byte from alphabet-b58 :: Alphabet -> Int -> Word8-b58 a i = BS.index (unAlphabet a) i---- | Lookup position of byte 'w' in alphabet-b58' :: Alphabet -> Word8 -> Maybe Int-b58' a w = BS.elemIndex w (unAlphabet a)- encodeBase58I :: Alphabet -> Integer -> ByteString encodeBase58I alpha i =     BC.pack $ showIntAtBase 58 f i ""@@ -60,14 +31,13 @@     f = chr . fromIntegral . b58 alpha . fromIntegral  decodeBase58I :: Alphabet -> ByteString -> Maybe Integer-decodeBase58I alpha s = case go of-    Just (r,[]) -> Just r-    _           -> Nothing-  where-    c = b58' alpha . fromIntegral . ord-    p = isJust . c-    f = fromIntegral . fromJust . c-    go = listToMaybe $ readInt 58 p f (BC.unpack s)+decodeBase58I alpha s =+    let c = b58' alpha . fromIntegral . ord+        p = isJust . c+        f = fromIntegral . fromJust . c+    in case readInt 58 p f (BC.unpack s) of+        [(r,[])] -> Just r+        _        -> Nothing  -- | Encode a bytestring to a base 58 representation. encodeBase58 :: Alphabet -> ByteString -> ByteString@@ -91,19 +61,3 @@         r | BS.null b = Just BS.empty           | otherwise = integerToBS <$> decodeBase58I alpha b     in BS.append prefix <$> r---- | Decode a big endian Integer from a bytestring-bsToInteger :: ByteString -> Integer-bsToInteger = (L.foldl' f 0) . BS.unpack-  where-    f n w = (toInteger w) .|. shiftL n 8---- | Encode an Integer to a bytestring as big endian-integerToBS :: Integer -> ByteString-integerToBS 0 = BS.pack [0]-integerToBS i-    | i > 0     = BS.pack $ reverse $ L.unfoldr f i-    | otherwise = error "integerToBS not defined for negative values"-  where-    f 0 = Nothing-    f x = Just $ (fromInteger x :: Word8, x `shiftR` 8)
+ src/Data/ByteString/Base58/Internal.hs view
@@ -0,0 +1,55 @@+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+    { unAlphabet  :: ByteString+    } deriving (Ord, Eq, Show, Typeable, Generic, IsString)+++bitcoinAlphabet :: Alphabet+bitcoinAlphabet =+    "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"++rippleAlphabet :: Alphabet+rippleAlphabet =+    "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"++flickrAlphabet :: Alphabet+flickrAlphabet =+    "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"++-- | Take 'i' byte from alphabet+b58 :: Alphabet -> Int -> Word8+b58 a i = BS.index (unAlphabet a) i++-- | Lookup position of byte 'w' in alphabet+b58' :: Alphabet -> Word8 -> Maybe Int+b58' a w = BS.elemIndex w (unAlphabet a)+++-- | Decode a big endian Integer from a bytestring+bsToInteger :: ByteString -> Integer+bsToInteger = (L.foldl' f 0) . BS.unpack+  where+    f n w = (toInteger w) .|. shiftL n 8++-- | Encode an Integer to a bytestring as big endian+integerToBS :: Integer -> ByteString+integerToBS 0 = BS.pack [0]+integerToBS i+    | i > 0     = BS.pack $ reverse $ L.unfoldr f i+    | otherwise = error "integerToBS not defined for negative values"+  where+    f 0 = Nothing+    f x = Just $ (fromInteger x :: Word8, x `shiftR` 8)