ppad-base58 0.1.0 → 0.1.1
raw patch · 4 files changed
+62/−13 lines, 4 filesdep +tasty-quickcheckPVP ok
version bump matches the API change (PVP)
Dependencies added: tasty-quickcheck
API changes (from Hackage documentation)
Files
- CHANGELOG +3/−0
- lib/Data/ByteString/Base58.hs +11/−10
- ppad-base58.cabal +2/−1
- test/Main.hs +46/−2
CHANGELOG view
@@ -1,5 +1,8 @@ # Changelog +- 0.1.1 (2025-01-06)+ * Includes a minor encoding-related performance optimisation.+ - 0.1.0 (2024-12-18) * Initial release, supporting basic encoding/decoding.
lib/Data/ByteString/Base58.hs view
@@ -19,6 +19,7 @@ import qualified Data.Bits as B import Data.Bits ((.|.)) import qualified Data.ByteString as BS+import qualified Data.ByteString.Unsafe as BU fi :: (Integral a, Num b) => a -> b fi = fromIntegral@@ -74,6 +75,15 @@ | h == 0x31 -> go (BS.cons 0x00 acc) t | otherwise -> acc +-- to base256+unroll_base256 :: Integer -> BS.ByteString+unroll_base256 = BS.reverse . BS.unfoldr coalg where+ coalg a+ | a == 0 = Nothing+ | otherwise = Just $+ let (b, c) = quotRem a 256+ in (fi c, b)+ -- from base256 roll_base256 :: BS.ByteString -> Integer roll_base256 = BS.foldl' alg 0 where@@ -86,7 +96,7 @@ | a == 0 = Nothing | otherwise = Just $ let (b, c) = quotRem a 58- in (BS.index base58_charset (fi c), b)+ in (BU.unsafeIndex base58_charset (fi c), b) -- from base58 roll_base58 :: BS.ByteString -> Integer@@ -95,13 +105,4 @@ Just w -> b * 58 + fi w Nothing -> error "ppad-base58 (roll_base58): not a base58-encoded bytestring"---- to base256-unroll_base256 :: Integer -> BS.ByteString-unroll_base256 = BS.reverse . BS.unfoldr coalg where- coalg a- | a == 0 = Nothing- | otherwise = Just $- let (b, c) = quotRem a 256- in (fi c, b)
ppad-base58.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: ppad-base58-version: 0.1.0+version: 0.1.1 synopsis: base58 and base58check encoding/decoding. license: MIT license-file: LICENSE@@ -47,6 +47,7 @@ , ppad-base58 , tasty , tasty-hunit+ , tasty-quickcheck , text benchmark base58-bench
test/Main.hs view
@@ -12,8 +12,10 @@ import qualified Data.ByteString.Base58Check as B58Check import qualified Data.Text.Encoding as TE import qualified Data.Text.IO as TIO+import Data.Word (Word8) import Test.Tasty import Test.Tasty.HUnit+import qualified Test.Tasty.QuickCheck as Q data Valid_Base58Check = Valid_Base58Check { vc_string :: !BS.ByteString@@ -78,6 +80,40 @@ let enc = B58.encode vb_decodedHex assertEqual mempty enc vb_encoded +newtype BS = BS BS.ByteString+ deriving (Eq, Show)++bytes :: Int -> Q.Gen BS.ByteString+bytes k = do+ l <- Q.chooseInt (0, k)+ v <- Q.vectorOf l Q.arbitrary+ pure (BS.pack v)++data B58C = B58C Word8 BS+ deriving (Eq, Show)++instance Q.Arbitrary BS where+ arbitrary = do+ b <- bytes 1024+ pure (BS b)++instance Q.Arbitrary B58C where+ arbitrary = do+ w8 <- Q.arbitrary+ bs <- Q.arbitrary+ pure (B58C w8 bs)++base58_decode_inverts_encode :: BS -> Bool+base58_decode_inverts_encode (BS bs) = case B58.decode (B58.encode bs) of+ Nothing -> False+ Just b -> b == bs++base58check_decode_inverts_encode :: B58C -> Bool+base58check_decode_inverts_encode (B58C w8 (BS bs)) =+ case B58Check.decode (B58Check.encode w8 bs) of+ Nothing -> False+ Just (w8', bs') -> w8 == w8' && bs == bs'+ main :: IO () main = do scure_base58 <- TIO.readFile "etc/base58.json"@@ -89,7 +125,15 @@ case per of Nothing -> error "couldn't parse vectors" Just (b58, b58c) -> defaultMain $ testGroup "ppad-base58" [- testGroup "base58" (fmap execute_base58 b58)- , execute_base58check b58c+ testGroup "unit tests" [+ testGroup "base58" (fmap execute_base58 b58)+ , execute_base58check b58c+ ]+ , testGroup "property tests" [+ Q.testProperty "(base58) decode . encode ~ id" $+ Q.withMaxSuccess 250 base58_decode_inverts_encode+ , Q.testProperty "(base58check) decode . encode ~ id" $+ Q.withMaxSuccess 250 base58check_decode_inverts_encode+ ] ]