diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
 |:---------------:|:---------------:|
 |encoding         | 400             |
 |decoding         | 400             |
-|lenient decoding | N/A             |
+|lenient decoding | 250             |
 
 ### Build Status [![Build Status][travis-img]][travis-log]
 
diff --git a/base32-bytestring.cabal b/base32-bytestring.cabal
--- a/base32-bytestring.cabal
+++ b/base32-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                base32-bytestring
-version:             0.1.0.0
+version:             0.1.1.0
 license:             BSD3
 license-file:        LICENSE
 author:              Sam Truzjan
@@ -16,12 +16,9 @@
   <http://tools.ietf.org/html/rfc4648>
   .
   The package API is similar to base64-bytestring.
-  .
-  [/Release notes/]
-  .
-    * /0.1.0.0:/ Initial version.
 
 extra-source-files:    README.md
+                     , changelog
 
 source-repository head
   type:                git
@@ -32,7 +29,7 @@
   type:                git
   location:            git://github.com/cobit/base32-bytestring.git
   branch:              master
-  tag:                 v0.1.0.0
+  tag:                 v0.1.1.0
 
 library
   default-language:    Haskell2010
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -17,10 +17,10 @@
   , bench "base32/decode/regular/5M" $ nf Base32.decode
       $ BS.replicate 5000000 0x41
 
---  , bench "base32/decode/lenient/1M" $ nf Base32.decodeLenient
---      $ BS.replicate 1000000 0x41
---  , bench "base32/decode/lenient/5M" $ nf Base32.decodeLenient
---      $ BS.replicate 5000000 0x41
+  , bench "base32/decode/lenient/1M" $ nf Base32.decodeLenient
+      $ BS.replicate 1000000 0x41
+  , bench "base32/decode/lenient/5M" $ nf Base32.decodeLenient
+      $ BS.replicate 5000000 0x41
 
   , bench "base32hex/encode/1M" $ nf Base32Hex.encode
       $ BS.replicate 1000000 0x8e
@@ -32,8 +32,8 @@
   , bench "base32hex/decode/regular/5M" $ nf Base32Hex.decode
       $ BS.replicate 5000000 0x41
 
---  , bench "base32hex/decode/lenient/1M" $ nf Base32Hex.decodeLenient
---      $ BS.replicate 1000000 0x41
---  , bench "base32hex/decode/lenient/5M" $ nf Base32Hex.decodeLenient
---      $ BS.replicate 5000000 0x41
+  , bench "base32hex/decode/lenient/1M" $ nf Base32Hex.decodeLenient
+      $ BS.replicate 1000000 0x41
+  , bench "base32hex/decode/lenient/5M" $ nf Base32Hex.decodeLenient
+      $ BS.replicate 5000000 0x41
   ]
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,2 @@
+* 0.1.0.0: Initial version.
+* 0.1.1.0: Added lenient decoding.
diff --git a/src/Data/ByteString/Base32.hs b/src/Data/ByteString/Base32.hs
--- a/src/Data/ByteString/Base32.hs
+++ b/src/Data/ByteString/Base32.hs
@@ -17,11 +17,10 @@
        ( Base32
        , encode
        , decode
---       , decodeLenient
+       , decodeLenient
        ) where
 
 import Data.ByteString as BS
-import Data.ByteString.Internal as BS
 import Data.ByteString.Base32.Internal
 import Data.List as L
 
@@ -56,27 +55,12 @@
 decTable :: ByteString
 decTable = BS.pack $ L.map decW5 [minBound .. maxBound]
 
--- | Decode a base32 encoded bytestring.
+-- | Decode a base32 encoded bytestring. This functions is
+-- case-insensitive and do not requires correct padding.
 decode :: Base32 -> ByteString
 decode = pack5 decTable
 
-decCharLenient :: Char -> Word5
-decCharLenient x
-  | x <  '2'  = err
-  | x <= '7'  = 26 + fromIntegral (fromEnum x) - fromIntegral (fromEnum '2')
-  | x <  'A'  = err
-  | x <= 'Z'  = fromIntegral (fromEnum x) - fromIntegral (fromEnum 'A')
-  | x <  'a'  = err
-  | x <= 'z'  = fromIntegral (fromEnum x) - fromIntegral (fromEnum 'a')
-  | otherwise = err
-  where
-    err = error "base32: decodeChar: out of range"
-
-decW5Lenient :: Word8 -> Word5
-decW5Lenient = decCharLenient . w2c
-{-# INLINE decW5Lenient #-}
-
--- TODO padding leniency
--- | Case-insensitive counterpart of the 'decode'.
+-- | The same as 'decode' but with additional leniency: decodeLenient
+-- will skip non-alphabet characters.
 decodeLenient :: Base32 -> ByteString
-decodeLenient = id -- pack5 nullPtr decW5Lenient
+decodeLenient = pack5Lenient decTable
diff --git a/src/Data/ByteString/Base32/Hex.hs b/src/Data/ByteString/Base32/Hex.hs
--- a/src/Data/ByteString/Base32/Hex.hs
+++ b/src/Data/ByteString/Base32/Hex.hs
@@ -17,7 +17,7 @@
        ( Base32Hex
        , encode
        , decode
---       , decodeLenient
+       , decodeLenient
        ) where
 
 import Data.ByteString as BS
@@ -53,9 +53,12 @@
 decTable :: DecTable
 decTable = BS.pack $ L.map decW5 [minBound .. maxBound]
 
--- | Decode a base32hex encoded bytestring.
+-- | Decode a base32hex encoded bytestring. This functions is
+-- case-insensitive and do not requires correct padding.
 decode :: Base32Hex -> ByteString
 decode = pack5 decTable
 
+-- | The same as 'decode' but with additional leniency: decodeLenient
+-- will skip non-alphabet characters.
 decodeLenient :: Base32Hex -> ByteString
-decodeLenient = id
+decodeLenient = pack5Lenient decTable
diff --git a/src/Data/ByteString/Base32/Internal.hs b/src/Data/ByteString/Base32/Internal.hs
--- a/src/Data/ByteString/Base32/Internal.hs
+++ b/src/Data/ByteString/Base32/Internal.hs
@@ -18,6 +18,7 @@
 
        , DecTable
        , pack5
+       , pack5Lenient
        , invIx
        ) where
 
@@ -228,3 +229,17 @@
     unsafePerformIO $ do
       withForeignPtr fptr $ \ptr ->
         return $ pack5Ptr (ptr `advancePtr` off) bs
+
+{-----------------------------------------------------------------------
+-- Lenient Decoding
+-----------------------------------------------------------------------}
+
+isInAlphabet :: Ptr Word5 -> Word8 -> Bool
+isInAlphabet !tbl !ix =
+  inlinePerformIO (peekByteOff tbl (fromIntegral ix)) /= invIx
+
+pack5Lenient :: DecTable -> ByteString -> ByteString
+pack5Lenient tbl @ (PS fptr _ _) bs =
+  unsafePerformIO $ do
+    withForeignPtr fptr $ \ !tbl_ptr -> do
+      return $! pack5 tbl $ BS.filter (isInAlphabet tbl_ptr) bs
