diff --git a/Data/Base58Address.hs b/Data/Base58Address.hs
--- a/Data/Base58Address.hs
+++ b/Data/Base58Address.hs
@@ -2,9 +2,10 @@
 #ifdef TESTS
 module Data.Base58Address (BitcoinAddress, RippleAddress, RippleAddress0(..)) where
 #else
-module Data.Base58Address (BitcoinAddress, RippleAddress) where
+module Data.Base58Address (BitcoinAddress, bitcoinAddressPayload, RippleAddress, rippleAddressPayload) where
 #endif
 
+import Control.Monad (guard)
 import Control.Arrow ((***))
 import Data.Word
 import Data.Binary (Binary(..), putWord8)
@@ -21,8 +22,10 @@
 instance Arbitrary Base58Address where
 	arbitrary = do
 		ver <- arbitrary
-		adr <- arbitrary `suchThat` (>=0)
-		return $ Base58Address ver adr
+		Positive adr <- arbitrary
+		let bsiz = length (toBase 256 adr)
+		plen <- choose (bsiz,bsiz+100)
+		return $ Base58Address ver adr plen
 
 instance Arbitrary BitcoinAddress where
 	arbitrary = fmap BitcoinAddress arbitrary
@@ -36,7 +39,7 @@
 instance Arbitrary RippleAddress0 where
 	arbitrary = do
 		adr <- arbitrary `suchThat` (>=0)
-		return $ RippleAddress0 $ RippleAddress $ Base58Address 0 adr
+		return $ RippleAddress0 $ RippleAddress $ Base58Address 0 adr 20
 #endif
 
 newtype BitcoinAddress = BitcoinAddress Base58Address
@@ -45,6 +48,9 @@
 bitcoinAlphabet :: Alphabet
 bitcoinAlphabet = read "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
 
+bitcoinAddressPayload :: BitcoinAddress -> Integer
+bitcoinAddressPayload (BitcoinAddress (Base58Address _ p _)) = p
+
 instance Show BitcoinAddress where
 	show (BitcoinAddress adr) = showB58 bitcoinAlphabet adr
 
@@ -59,6 +65,9 @@
 rippleAlphabet :: Alphabet
 rippleAlphabet = read "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz"
 
+rippleAddressPayload :: RippleAddress -> Integer
+rippleAddressPayload (RippleAddress (Base58Address _ p _)) = p
+
 instance Show RippleAddress where
 	show (RippleAddress adr) = showB58 rippleAlphabet adr
 
@@ -70,32 +79,35 @@
 instance Binary RippleAddress where
 	get = do
 		value <- (fromBase 256 . BS.unpack) `fmap` getByteString 20
-		return $ RippleAddress (Base58Address 0 value)
+		return $ RippleAddress (Base58Address 0 value 20)
 
-	put (RippleAddress (Base58Address 0 value)) = do
+	put (RippleAddress (Base58Address 0 value 20)) = do
 		let bytes = toBase 256 value
 		mapM_ putWord8 (replicate (20 - length bytes) 0 ++ bytes)
-	put _ = fail "RippleAddress version is always 0"
+	put _ = fail "RippleAddress account ID is always 0, length always 20"
 
-data Base58Address = Base58Address !Word8 !Integer
-	deriving (Ord, Eq)
+-- Version, payload, payload bytesize
+data Base58Address = Base58Address !Word8 !Integer !Int
+	deriving (Show, Ord, Eq)
 
 showB58 :: Alphabet -> Base58Address -> String
-showB58 alphabet (Base58Address version addr) = prefix ++
-	toString alphabet 58 (fromBase 256 (bytes' ++ mkChk bytes') :: Integer)
+showB58 alphabet (Base58Address version addr plen) = prefix ++
+	toString alphabet 58 (fromBase 256 (bytes ++ mkChk bytes) :: Integer)
 	where
-	prefix | version == 0 = toString alphabet 58 0
-	       | otherwise = ""
-	bytes' = version : replicate (20 - length bytes) 0 ++ bytes
-	bytes = toBase 256 addr
+	prefix = replicate (length $ takeWhile (==0) bytes) z
+	bytes = version : replicate (plen - length bytes') 0 ++ bytes'
+	bytes' = toBase 256 addr
+	Just z = toAlphaDigit alphabet 0
 
 decodeB58 :: Alphabet -> String -> Maybe Base58Address
 decodeB58 alphabet s = do
-	(chk,bytes) <- fmap (splitChk . toBase 256)
-		(toIntegral alphabet 58 s :: Maybe Integer)
-	let bytes' = replicate (21 - length bytes) 0 ++ bytes
-	if mkChk bytes' /= chk then Nothing else
-		Just $! Base58Address (head bytes') (fromBase 256 (tail bytes'))
+	(zs,digits) <- fmap (span (==0)) (toDigits alphabet s)
+	let (chk,bytes) = splitChk $ toBase 256 $ fromBase 58 digits
+	case map fromIntegral zs ++ bytes of
+		[] -> Nothing
+		(version:bytes') -> do
+			guard (mkChk (version:bytes') == chk)
+			return $! Base58Address version (fromBase 256 bytes') (length bytes')
 
 splitChk :: [a] -> ([a], [a])
 splitChk = (reverse *** reverse) . splitAt 4 . reverse
diff --git a/Data/Base58Address/Alphabet.hs b/Data/Base58Address/Alphabet.hs
--- a/Data/Base58Address/Alphabet.hs
+++ b/Data/Base58Address/Alphabet.hs
@@ -30,5 +30,7 @@
 fromAlphaDigit (Alphabet _ indices) v = Map.lookup v indices
 
 toIntegral :: (Integral a) => Alphabet -> a -> String -> Maybe a
-toIntegral a b = fmap (fromBase b) .
-	mapM (fmap toInteger . fromAlphaDigit a)
+toIntegral a b = fmap (fromBase b) . toDigits a
+
+toDigits :: Alphabet -> String -> Maybe [Integer]
+toDigits a = mapM (fmap toInteger . fromAlphaDigit a)
diff --git a/base58address.cabal b/base58address.cabal
--- a/base58address.cabal
+++ b/base58address.cabal
@@ -1,5 +1,5 @@
 name:            base58address
-version:         0.3
+version:         0.4
 cabal-version:   >= 1.8
 license:         OtherLicense
 license-file:    COPYING
