diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -13,3 +13,4 @@
 * [Timo von Holtz](http://github.com/tvh)
 * [Brendan Hay](http://github.com/brendanhay)
 * [k0ral](https://github.com/k0ral)
+* [Michael Hatfield](https://github.com/mikehat)
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+0.2.2.0
+* Internally use attoparsec's numeric parser. Raise lower bounds on attoparsec.
+* Allow blank fragments.
+
 0.2.1.2
 * Fixed bug introduced at 0.2.1.1 where RelativeRefs would fail to serialize their port numbers.
 
diff --git a/src/URI/ByteString/Internal.hs b/src/URI/ByteString/Internal.hs
--- a/src/URI/ByteString/Internal.hs
+++ b/src/URI/ByteString/Internal.hs
@@ -13,6 +13,7 @@
 import           Control.Monad
 import           Data.Attoparsec.ByteString
 import qualified Data.Attoparsec.ByteString         as A
+import qualified Data.Attoparsec.ByteString.Char8   as A ( decimal )
 import           Data.Bits
 import           Data.ByteString                    (ByteString)
 import qualified Data.ByteString                    as BS
@@ -512,12 +513,12 @@
                                   , dot
                                   , decOctet]
   where
+    decOctet :: Parser ByteString
     decOctet = do
-      s <- A.takeWhile1 isDigit
+      (s,num) <- A.match A.decimal
       let len = BS.length s
-      guard $ len > 0 && len <= 3
-      let num = bsToNum s
-      guard $ num >= 1 && num <= 255
+      guard $ len <= 3
+      guard $ num >= (1 :: Int) && num <= 255
       return s
     dot = string "."
 
@@ -540,7 +541,7 @@
 -- | Parses port number from the hostname. Colon separator must be
 -- handled elsewhere.
 portParser :: URIParser Port
-portParser = (Port . bsToNum <$> A.takeWhile1 isDigit) `orFailWith` MalformedPort
+portParser = (Port <$> A.decimal) `orFailWith` MalformedPort
 
 
 -------------------------------------------------------------------------------
@@ -620,13 +621,13 @@
 -------------------------------------------------------------------------------
 -- | Only parses a fragment if the # signifiier is there
 mFragmentParser :: URIParser (Maybe ByteString)
-mFragmentParser = word8' hash `thenJust` fragmentParser
+mFragmentParser = mParse $ word8' hash *> fragmentParser
 
 
 -------------------------------------------------------------------------------
 -- | The final piece of a uri, e.g. #fragment, minus the #.
 fragmentParser :: URIParser ByteString
-fragmentParser = A.takeWhile1 validFragmentWord `orFailWith` MalformedFragment
+fragmentParser = Parser' $ A.takeWhile validFragmentWord
   where
     validFragmentWord = inClass ('?':'/':pchar)
 
@@ -754,17 +755,6 @@
 -------------------------------------------------------------------------------
 -- | ByteString Utilities
 -------------------------------------------------------------------------------
-
--- FIXME: theres probably a much better way to do this
-
--------------------------------------------------------------------------------
--- | Convert a bytestring into an int representation. Assumes the
--- entire string is comprised of 0-9 digits.
-bsToNum :: ByteString -> Int
-bsToNum s = sum $ zipWith (*) (reverse ints) [10 ^ x | x <- [0..] :: [Int]]
-  where
-    w2i w = fromEnum $ w - 48
-    ints  = map w2i . BS.unpack $ s
 
 
 -------------------------------------------------------------------------------
diff --git a/test/URI/ByteStringTests.hs b/test/URI/ByteStringTests.hs
--- a/test/URI/ByteStringTests.hs
+++ b/test/URI/ByteStringTests.hs
@@ -91,6 +91,12 @@
           "/foo"
           mempty
           (Just "bar")
+  , testParses "http://www.example.org/foo#" $
+      URI (Scheme "http")
+          (Just (Authority Nothing (Host "www.example.org") Nothing))
+          "/foo"
+          mempty
+          (Just "")
   , testParseFailure "http://www.example.org/foo#bar#baz" MalformedFragment
   , testParseFailure "https://www.example.org?listParam[]=foo,bar" MalformedQuery
   , testParsesLax "https://www.example.org?listParam[]=foo,bar" $
diff --git a/uri-bytestring.cabal b/uri-bytestring.cabal
--- a/uri-bytestring.cabal
+++ b/uri-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                uri-bytestring
-version:             0.2.1.2
+version:             0.2.2.0
 synopsis:            Haskell URI parsing as ByteStrings
 description: uri-bytestring aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the URI data.
 license:             BSD3
@@ -36,7 +36,7 @@
 
   build-depends:
 
-      attoparsec       >= 0.10    && < 0.14
+      attoparsec       >= 0.12    && < 0.14
     , base             >= 4.6     && < 4.10
     , bytestring       >= 0.9.1   && < 0.11
     , blaze-builder    >= 0.3.0.0 && < 0.5
