diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -12,10 +12,10 @@
 |Segmented OSI Model |
 +--------------------+
 
- magic, where XXXX is a feed type
-+---------------------+-------------+
-| "seg:XXXX" [char:8] | ver: uint64 |
-+---------------------+-------------+
+ magic, where XXXX is a feed type (0-12 chars)
++----------------------+
+| "seg:XXXX" [char:16] |
++----------------------+
 
 c -- countries
 a -- asns
diff --git a/app/App/Commands/DumpBitmap.hs b/app/App/Commands/DumpBitmap.hs
--- a/app/App/Commands/DumpBitmap.hs
+++ b/app/App/Commands/DumpBitmap.hs
@@ -8,8 +8,8 @@
   ) where
 
 import App.Commands.Options.Type
-import App.Dump
 import Arbor.File.Format.Asif.Data.Ip
+import Arbor.File.Format.Asif.Extract (bitmap)
 import Arbor.File.Format.Asif.IO
 import Control.Lens
 import Control.Monad
@@ -19,10 +19,8 @@
 import Data.Monoid                    ((<>))
 import Options.Applicative
 
-import qualified Arbor.File.Format.Asif.ByteString.Lazy as LBS
-import qualified Data.Binary.Get                        as G
-import qualified Data.ByteString.Lazy                   as LBS
-import qualified System.IO                              as IO
+import qualified Data.ByteString.Lazy as LBS
+import qualified System.IO            as IO
 
 {-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}
 {-# ANN module ("HLint: ignore Redundant do"        :: String) #-}
@@ -52,7 +50,7 @@
 
   contents <- liftIO $ LBS.hGetContents hIn
 
-  forM_ (zip [0..] (G.runGet G.getWord64le <$> LBS.chunkBy 8 contents)) $ \(idx, w64) ->
-    forM_ (word64ToList idx w64 []) $ \w32 -> do
-      let ipString = w32 & word32ToIpv4 & ipv4ToString
-      liftIO $ IO.hPutStrLn hOut $ ipString <> replicate (16 - length ipString) ' ' <> "(" <> show w32 <> ")"
+  forM_ (bitmap contents) $ \ip ->
+    let ipString = ipv4ToString ip
+        w32 = ipv4ToWord32 ip
+    in liftIO $ IO.hPutStrLn hOut $ ipString <> replicate (16 - length ipString) ' ' <> "(" <> show w32 <> ")"
diff --git a/app/App/Dump.hs b/app/App/Dump.hs
--- a/app/App/Dump.hs
+++ b/app/App/Dump.hs
@@ -5,10 +5,10 @@
 
 module App.Dump
   ( dumpSegment
-  , word64ToList
   ) where
 
 import Arbor.File.Format.Asif.Data.Ip
+import Arbor.File.Format.Asif.Extract
 import Arbor.File.Format.Asif.Segment
 import Arbor.File.Format.Asif.Whatever
 import Control.Lens
@@ -22,9 +22,7 @@
 import Data.Text                       (Text)
 import Data.Thyme.Format               (formatTime)
 import Data.Thyme.Time.Core
-import Data.Word
 import HaskellWorks.Data.Bits.BitShow
-import HaskellWorks.Data.Bits.BitWise
 import Numeric                         (showHex)
 import System.IO                       (Handle)
 import System.Locale                   (defaultTimeLocale, iso8601DateFormat)
@@ -34,7 +32,6 @@
 import qualified Arbor.File.Format.Asif.Get             as D
 import qualified Data.Binary                            as G
 import qualified Data.Binary.Get                        as G
-import qualified Data.Bits                              as B
 import qualified Data.ByteString.Lazy                   as LBS
 import qualified Data.ByteString.Lazy.Char8             as LBSC
 import qualified Data.Text                              as T
@@ -49,13 +46,6 @@
 showTime :: FormatTime t => t -> String
 showTime = formatTime defaultTimeLocale (iso8601DateFormat (Just "%H:%M:%S %Z"))
 
-word64ToList :: Int -> Word64 -> [Word32] -> [Word32]
-word64ToList _ 0 = id
-word64ToList o w = (ip:) . word64ToList o (w .&. comp b)
-  where p  = B.countTrailingZeros w
-        hi = o .<. 6
-        ip = fromIntegral (p .|. hi)
-        b  = 1 .<. fromIntegral p
 
 dumpSegment :: MonadResource m => Handle -> Int -> Text -> Segment LBS.ByteString -> m ()
 dumpSegment hOut i filename segment = do
@@ -163,10 +153,10 @@
       liftIO $ IO.hPutStrLn hOut (bitShow (segment ^. the @"payload"))
 
     Just (Known F.Bitmap) ->
-      forM_ (zip [0..] (G.runGet G.getWord64le <$> LBS.chunkBy 8 (segment ^. the @"payload"))) $ \(idx, w64) ->
-        forM_ (word64ToList idx w64 []) $ \w32 -> do
-          let ipString = w32 & word32ToIpv4 & ipv4ToString
-          liftIO $ IO.hPutStrLn hOut $ ipString <> replicate (16 - length ipString) ' ' <> "(" <> show w32 <> ")"
+      forM_ (bitmap $ segment ^. the @"payload") $ \ip ->
+        let ipString = ipv4ToString ip
+            w32 = ipv4ToWord32 ip
+        in liftIO $ IO.hPutStrLn hOut $ ipString <> replicate (16 - length ipString) ' ' <> "(" <> show w32 <> ")"
 
     Just (Known F.Bool) ->
       forM_ (LBS.chunkBy 1 (segment ^. the @"payload")) $ \bs -> do
diff --git a/asif.cabal b/asif.cabal
--- a/asif.cabal
+++ b/asif.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           asif
-version:        6.0.0
+version:        6.0.1
 description:    Library for creating and querying segmented feeds. Please see <https://github.com/arbor/asif#readme>
 synopsis:       Library for creating and querying segmented feeds
 category:       Services
diff --git a/src/Arbor/File/Format/Asif/ByteString/Builder.hs b/src/Arbor/File/Format/Asif/ByteString/Builder.hs
--- a/src/Arbor/File/Format/Asif/ByteString/Builder.hs
+++ b/src/Arbor/File/Format/Asif/ByteString/Builder.hs
@@ -44,7 +44,7 @@
 magicPrefix = "seg:"
 
 -- magic file identifier for segmented gan feeds.
--- 7 characters. the 8th is meant to be filled in based on feed.
+-- 16 characters. the last 12 are meant to be filled in based on feed.
 magicString :: String -> LC8.ByteString
 magicString s = if LBS.length truncatedMagic < LBS.length rawMagic
   then truncatedMagic
diff --git a/src/Arbor/File/Format/Asif/Data/Ip.hs b/src/Arbor/File/Format/Asif/Data/Ip.hs
--- a/src/Arbor/File/Format/Asif/Data/Ip.hs
+++ b/src/Arbor/File/Format/Asif/Data/Ip.hs
@@ -13,13 +13,16 @@
   , ipv4ToWord32
   , ipv6ToWord32x4
   , ipv4ToIpv6
+  , word64ToIpList
   ) where
 
 import Arbor.File.Format.Asif.Data.Read
 import Control.Lens                     ((&))
 import Data.Word
+import HaskellWorks.Data.Bits.BitWise
 import Text.Read
 
+import qualified Data.Bits                         as B
 import qualified HaskellWorks.Data.Network.Ip.Ipv4 as IP4
 import qualified HaskellWorks.Data.Network.Ip.Ipv6 as IP6
 
@@ -77,3 +80,13 @@
 
 ipv4ToIpv6 :: IP4.IpAddress -> IP6.IpAddress
 ipv4ToIpv6 = IP6.fromIpv4
+
+-- This takes a Word64 from a Bitmap, and converts it to a list of IPs.
+-- The integer argument is an index into the bitmap
+word64ToIpList :: Int -> Word64 -> [Word32] -> [Word32]
+word64ToIpList _ 0 = id
+word64ToIpList o w = (ip:) . word64ToIpList o (w .&. comp b)
+  where p  = B.countTrailingZeros w
+        hi = o .<. 6
+        ip = fromIntegral (p .|. hi)
+        b  = 1 .<. fromIntegral p
diff --git a/src/Arbor/File/Format/Asif/Extract.hs b/src/Arbor/File/Format/Asif/Extract.hs
--- a/src/Arbor/File/Format/Asif/Extract.hs
+++ b/src/Arbor/File/Format/Asif/Extract.hs
@@ -12,8 +12,10 @@
   , map
   , vectorBoxed
   , vectorUnboxed
+  , bitmap
   ) where
 
+import Arbor.File.Format.Asif.Data.Ip
 import Arbor.File.Format.Asif.Format.Type (Format)
 import Arbor.File.Format.Asif.Whatever
 import Control.Lens
@@ -24,12 +26,14 @@
 import Data.Text.Encoding.Error
 import Prelude                            hiding (map)
 
-import qualified Data.Binary.Get      as G
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.List            as L
-import qualified Data.Map.Strict      as M
-import qualified Data.Vector          as V
-import qualified Data.Vector.Unboxed  as VU
+import qualified Arbor.File.Format.Asif.ByteString.Lazy as LBS
+import qualified Data.Binary.Get                        as G
+import qualified Data.ByteString.Lazy                   as LBS
+import qualified Data.List                              as L
+import qualified Data.Map.Strict                        as M
+import qualified Data.Vector                            as V
+import qualified Data.Vector.Unboxed                    as VU
+import qualified HaskellWorks.Data.Network.Ip.Ipv4      as IP4
 
 vectorBoxed :: Get a -> LBS.ByteString -> V.Vector a
 vectorBoxed g = V.unfoldr step
@@ -71,3 +75,8 @@
         convert (Left _)   = Nothing
         convert (Right "") = Nothing
         convert (Right t)  = Just (tReadWhatever t)
+
+bitmap :: LBS.ByteString -> [IP4.IpAddress]
+bitmap lbs =
+  zip [0..] (G.runGet G.getWord64le <$> LBS.chunkBy 8 lbs) >>= \(idx, w64) ->
+    word64ToIpList idx w64 [] <&> word32ToIpv4
