diff --git a/Hexdump.hs b/Hexdump.hs
new file mode 100644
--- /dev/null
+++ b/Hexdump.hs
@@ -0,0 +1,9 @@
+import Text.Bytedump
+import System.Environment (getArgs)
+
+import qualified Data.ByteString.Lazy as L
+
+main = do
+	args     <- getArgs
+	fileData <- L.readFile $ args !! 0
+	putStrLn $ dumpLBS fileData
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2010-2011 Vincent Hanquez <vincent@snarc.org>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+Haskell Bytedump library
+========================
+
+This is a set of helper to dump bytes (list of word8, string, bytestring, lazy bytestring)
+into nice to read tables like the unix utility hexdump.
+
+Example
+-------
+
+this is an example using the default configuration.
+
+```
+ | 7f 45 4c 46 02 01 01 00 : 00 00 00 00 00 00 00 00  | .ELF............
+ | 02 00 3e 00 01 00 00 00 : 68 5e 40 00 00 00 00 00  | ..>.....h^@.....
+ | 40 00 00 00 00 00 00 00 : 00 99 0a 00 00 00 00 00  | @...............
+ | 00 00 00 00 40 00 38 00 : 08 00 40 00 20 00 1d 00  | ....@.8...@. ...
+ | 06 00 00 00 05 00 00 00 : 40 00 00 00 00 00 00 00  | ........@.......
+ | 40 00 40 00 00 00 00 00 : 40 00 40 00 00 00 00 00  | @.@.....@.@.....
+ | c0 01 00 00 00 00 00 00 : c0 01 00 00 00 00 00 00  | ................
+ | 08 00 00 00 00 00 00 00 : 03 00 00 00 04 00 00 00  | ................
+ | 00 02 00 00 00 00 00 00 : 00 02 40 00 00 00 00 00  | ..........@.....
+ | 00 02 40 00 00 00 00 00 : 1c 00 00 00 00 00 00 00  | ..@.............
+ | 1c 00 00 00 00 00 00 00 : 01 00 00 00 00 00 00 00  | ................
+ | 01 00 00 00 05 00 00 00 : 00 00 00 00 00 00 00 00  | ................
+ | 00 00 40 00 00 00 00 00 : 00 00 40 00 00 00 00 00  | ..@.......@.....
+ | a4 e7 09 00 00 00 00 00 : a4 e7 09 00 00 00 00 00  | ................
+ | 00 00 20 00 00 00 00 00 : 01 00 00 00 06 00 00 00  | .. .............
+ | 00 f0 09 00 00 00 00 00 : 00 f0 69 00 00 00 00 00  | ..........i.....
+ | 00 f0 69 00 00 00 00 00 : 98 a7 00 00 00 00 00 00  | ..i.............
+ | 18 5f 01 00 00 00 00 00 : 00 00 20 00 00 00 00 00  | ._........ .....
+ | 02 00 00 00 06 00 00 00 : 30 f0 09 00 00 00 00 00  | ........0.......
+ | 30 f0 69 00 00 00 00 00 : 30 f0 69 00 00 00 00 00  | 0.i.....0.i.....
+```
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/Text/Bytedump.hs b/Text/Bytedump.hs
new file mode 100644
--- /dev/null
+++ b/Text/Bytedump.hs
@@ -0,0 +1,165 @@
+
+-- |
+-- Module      : Text.Bytedump
+-- License     : BSD-style
+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- A module containing some routines to debug data dump
+--
+
+module Text.Bytedump
+	( hexString
+
+	-- * Formatted string configuration
+	, BytedumpConfig(..)
+	, defaultConfig
+
+	-- * Dump bytes into not formatted strings
+	, dumpRaw
+	, dumpRawS
+	, dumpRawBS
+	, dumpRawLBS
+
+	-- * Dump bytes into formatted strings using a specific config
+	, dumpWith
+	, dumpWithS
+	, dumpWithBS
+	, dumpWithLBS
+
+	-- * Dump bytes into formatted strings using default config
+	, dump
+	, dumpS
+	, dumpBS
+	, dumpLBS
+	) where
+
+import Data.List
+import Data.Word
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString as B
+
+-- | Configuration structure used for formatting functions
+data BytedumpConfig = BytedumpConfig
+	{ configRowSize      :: Int    -- ^ number of bytes per row.
+	, configRowGroupSize :: Int    -- ^ number of bytes per group per row.
+	, configRowGroupSep  :: String -- ^ string separating groups.
+	, configRowLeft      :: String -- ^ string on the left of the row.
+	, configRowRight     :: String -- ^ string on the right of the row.
+	, configCellSep      :: String -- ^ string separating cells in row.
+	, configPrintChar    :: Bool   -- ^ if the printable ascii table is displayed.
+	} deriving (Show,Eq)
+
+-- | Default Config using 16 bytes by row with a separation at the 8th byte, and
+-- dumping printable ascii character on the right.
+defaultConfig :: BytedumpConfig
+defaultConfig = BytedumpConfig
+	{ configRowSize      = 16
+	, configRowGroupSize = 8
+	, configRowGroupSep  = " : "
+	, configRowLeft      = " | "
+	, configRowRight     = " | "
+	, configCellSep      = " "
+	, configPrintChar    = True
+	}
+
+hex :: Int -> Char
+hex 0  = '0'
+hex 1  = '1'
+hex 2  = '2'
+hex 3  = '3'
+hex 4  = '4'
+hex 5  = '5'
+hex 6  = '6'
+hex 7  = '7'
+hex 8  = '8'
+hex 9  = '9'
+hex 10 = 'a'
+hex 11 = 'b'
+hex 12 = 'c'
+hex 13 = 'd'
+hex 14 = 'e'
+hex 15 = 'f'
+hex _  = ' '
+
+{-# INLINE hexBytes #-}
+hexBytes :: Word8 -> (Char, Char)
+hexBytes w = (hex h, hex l) where (h,l) = (fromIntegral w) `divMod` 16
+
+-- | Dump one byte into a 2 hexadecimal characters.
+hexString :: Word8 -> String
+hexString i = [h,l] where (h,l) = hexBytes i
+
+-- | Dump a list of word8 into a raw string of hex value
+dumpRaw :: [Word8] -> String
+dumpRaw = concatMap hexString
+
+-- | Dump a string into a raw string of hex value
+dumpRawS :: String -> String
+dumpRawS = dumpRaw . map (toEnum.fromEnum)
+
+-- | Dump a bytestring into a raw string of hex value
+dumpRawBS :: B.ByteString -> String
+dumpRawBS = dumpRaw . B.unpack
+
+-- | Dump a lazy bytestring into a raw string of hex value
+dumpRawLBS :: L.ByteString -> String
+dumpRawLBS = dumpRaw . L.unpack
+
+disptable :: BytedumpConfig -> [Word8] -> [String]
+disptable _   [] = []
+disptable cfg x  =
+	let (pre, post) = splitAt (configRowSize cfg) x in
+	tableRow pre : disptable cfg post
+	where
+		tableRow row =
+			let l  = splitMultiple (configRowGroupSize cfg) $ map hexString row in
+			let lb = intercalate (configRowGroupSep cfg) $ map (intercalate (configCellSep cfg)) l in
+			let rb = map printChar row in
+			let rowLen = 2 * configRowSize cfg
+			           + (configRowSize cfg - 1) * length (configCellSep cfg)
+			           + ((configRowSize cfg `div` configRowGroupSize cfg) - 1) * length (configRowGroupSep cfg) in
+			configRowLeft cfg ++ lb ++ replicate (rowLen - length lb) ' ' ++ configRowRight cfg ++ (if configPrintChar cfg then rb else "")
+
+		splitMultiple _ [] = []
+		splitMultiple n l  = let (pre, post) = splitAt n l in pre : splitMultiple n post
+
+		printChar :: Word8 -> Char
+		printChar w
+			| w >= 0x20 && w < 0x7f = toEnum $ fromIntegral w
+			| otherwise             = '.'
+
+-- | Dump a list of bytes into formatted strings using a specific config
+dumpWith :: BytedumpConfig -> [Word8] -> String
+dumpWith cfg l = intercalate "\n" rows
+	where rows = disptable cfg l
+
+-- | Dump a string into formatted strings using a specific config
+dumpWithS :: BytedumpConfig -> String -> String
+dumpWithS cfg = dumpWith cfg . map (toEnum.fromEnum)
+
+-- | Dump a bytestring into formatted strings using a specific config
+dumpWithBS :: BytedumpConfig -> B.ByteString -> String
+dumpWithBS cfg = dumpWith cfg . B.unpack
+
+-- | Dump a lazy bytestring into formatted strings using a specific config
+dumpWithLBS :: BytedumpConfig -> L.ByteString -> String
+dumpWithLBS cfg = dumpWith cfg . L.unpack
+
+-- | Dump a list of word8 into a formatted string of hex value
+dump :: [Word8] -> String
+dump l = intercalate "\n" rows
+	where rows = disptable defaultConfig l
+
+-- | Dump a string into a formatted string of hex value
+dumpS :: String -> String
+dumpS = dump . map (toEnum.fromEnum)
+
+-- | Dump a bytestring into a formatted string of hex value
+dumpBS :: B.ByteString -> String
+dumpBS = dump . B.unpack
+
+-- | Dump a lazy bytestring into a formatted string of hex value
+dumpLBS :: L.ByteString -> String
+dumpLBS = dump . L.unpack
diff --git a/bytedump.cabal b/bytedump.cabal
new file mode 100644
--- /dev/null
+++ b/bytedump.cabal
@@ -0,0 +1,40 @@
+Name:                bytedump
+Version:             0.9
+Description:
+    A set of helpers to dump bytes with lots of different output formats
+    easy to read for humans eyes.
+License:             BSD3
+License-file:        LICENSE
+Author:              Vincent Hanquez
+Copyright:           Vincent Hanquez <vincent@snarc.org>
+Author:              Vincent Hanquez <vincent@snarc.org>
+Maintainer:          Vincent Hanquez <vincent@snarc.org>
+Synopsis:            Flexible byte dump helpers for human readers.
+Build-Type:          Simple
+Category:            Debug
+Homepage:            http://github.com/vincenthz/hs-bytedump
+Cabal-Version:       >=1.6
+Data-Files:          README.md
+
+Flag executable
+  Description:       Build the executable
+  Default:           False
+
+Library
+  Build-Depends:     base >= 3 && < 5
+                   , bytestring
+  Exposed-modules:   Text.Bytedump
+  ghc-options:       -Wall
+
+Executable           Hexdump
+  Main-is:           Hexdump.hs
+  if flag(executable)
+    Buildable:       True
+    Build-Depends:   base >= 3 && < 5
+                   , bytestring
+  else
+    Buildable:       False
+
+source-repository head
+  type: git
+  location: git://github.com/vincenthz/hs-bytedump
