diff --git a/rtcm.cabal b/rtcm.cabal
--- a/rtcm.cabal
+++ b/rtcm.cabal
@@ -1,5 +1,5 @@
 name:                  rtcm
-version:               0.1.2
+version:               0.1.3
 synopsis:              RTCM Library.
 description:           Haskell bindings for RTCM.
 homepage:              http://github.com/swift-nav/librtcm
diff --git a/src/Data/RTCM3.hs b/src/Data/RTCM3.hs
--- a/src/Data/RTCM3.hs
+++ b/src/Data/RTCM3.hs
@@ -10,21 +10,17 @@
 
 module Data.RTCM3
   ( RTCM3Msg (..)
-  , module Data.RTCM3.Types
   , module Data.RTCM3.Antennas
   , module Data.RTCM3.Observations
+  , module Data.RTCM3.Types
   ) where
 
-import           BasicPrelude
-import           Data.Binary
-import           Data.Binary.Get
-import qualified Data.Binary.Bits.Get as B
-import           Data.ByteString.Lazy
-import           Data.Word.Word24
-import           Data.RTCM3.Antennas
-import           Data.RTCM3.Extras
-import           Data.RTCM3.Observations
-import           Data.RTCM3.Types
+import BasicPrelude
+import Data.Binary
+import Data.ByteString.Lazy
+import Data.RTCM3.Antennas
+import Data.RTCM3.Observations
+import Data.RTCM3.Types
 
 -- | An RTCM message ADT composed of all defined RTCM messages.
 --
@@ -40,7 +36,7 @@
    | RTCM3Msg1007 Msg1007 Msg
    | RTCM3Msg1008 Msg1008 Msg
    | RTCM3MsgUnknown Word16 Msg
-   | RTCM3MsgBadCrc Word24 Msg
+   | RTCM3MsgBadCrc Msg
    deriving ( Show, Read, Eq )
 
 instance Binary RTCM3Msg where
@@ -48,34 +44,30 @@
     preamble <- getWord8
     if preamble /= msgRTCM3Preamble then get else do
       rtcm3 <- get
-      crc <- getWord24be
-      return $ decode' rtcm3 crc where
-        decode' rtcm3@Msg {..} crc
-          | checkCrc rtcm3 /= crc = RTCM3MsgBadCrc crc rtcm3
-          | otherwise = flip runGet (fromStrict _msgRTCM3Payload) $ B.runBitGet $ do
-              num <- B.getWord16be 12
-              return $ decode'' num where
-                decode'' num
-                  | num == msg1001 = RTCM3Msg1001 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1002 = RTCM3Msg1002 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1003 = RTCM3Msg1003 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1004 = RTCM3Msg1004 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1005 = RTCM3Msg1005 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1006 = RTCM3Msg1006 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1007 = RTCM3Msg1007 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | num == msg1008 = RTCM3Msg1008 (decode $ fromStrict _msgRTCM3Payload) rtcm3
-                  | otherwise = RTCM3MsgUnknown num rtcm3
+      return $ decode' rtcm3  where
+        decode' rtcm3@Msg {..}
+          | checkCrc _msgRTCM3Len _msgRTCM3Payload /= _msgRTCM3Crc = RTCM3MsgBadCrc rtcm3
+          | num == msg1001 = RTCM3Msg1001 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1002 = RTCM3Msg1002 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1003 = RTCM3Msg1003 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1004 = RTCM3Msg1004 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1005 = RTCM3Msg1005 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1006 = RTCM3Msg1006 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1007 = RTCM3Msg1007 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | num == msg1008 = RTCM3Msg1008 (decode $ fromStrict _msgRTCM3Payload) rtcm3
+          | otherwise = RTCM3MsgUnknown num rtcm3 where
+            num = checkNum _msgRTCM3Payload
 
   put msg = do
     putWord8 msgRTCM3Preamble
     encode' msg where
-      encode' (RTCM3Msg1001 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1002 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1003 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1004 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1005 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1006 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1007 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3Msg1008 _msg rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3MsgUnknown _num rtcm3) = put rtcm3 >> putWord24be (checkCrc rtcm3)
-      encode' (RTCM3MsgBadCrc crc rtcm3) = put rtcm3 >> putWord24be crc
+      encode' (RTCM3Msg1001 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1002 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1003 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1004 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1005 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1006 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1007 _msg rtcm3) = put rtcm3
+      encode' (RTCM3Msg1008 _msg rtcm3) = put rtcm3
+      encode' (RTCM3MsgUnknown _num rtcm3) = put rtcm3
+      encode' (RTCM3MsgBadCrc rtcm3) = put rtcm3
diff --git a/src/Data/RTCM3/TH.hs b/src/Data/RTCM3/TH.hs
--- a/src/Data/RTCM3/TH.hs
+++ b/src/Data/RTCM3/TH.hs
@@ -12,7 +12,8 @@
 
 import BasicPrelude hiding ( length )
 import Data.Binary
-import Data.ByteString.Lazy
+import Data.ByteString
+import Data.ByteString.Lazy hiding ( length )
 import Data.RTCM3.Types
 import Language.Haskell.TH
 
@@ -21,6 +22,8 @@
 deriveRTCM3 :: Name -> Q [Dec]
 deriveRTCM3 name =
   [d|instance ToRTCM3 $(conT name) where
-       toRTCM3 msg = Msg (fromIntegral $ length payload) (toStrict payload) where
-         payload = encode msg
+       toRTCM3 msg = Msg len payload crc where
+         payload = toStrict $ encode msg
+         len     = fromIntegral $ length payload
+         crc     = checkCrc len payload
     |]
diff --git a/src/Data/RTCM3/Types.hs b/src/Data/RTCM3/Types.hs
--- a/src/Data/RTCM3/Types.hs
+++ b/src/Data/RTCM3/Types.hs
@@ -15,10 +15,12 @@
 import           Control.Lens
 import           Data.Binary
 import qualified Data.Binary.Bits.Get as B
-import qualified Data.Binary.Bits.Put as B
 import           Data.Binary.Get
 import           Data.Binary.Put
+import           Data.ByteString.Builder
+import           Data.ByteString.Lazy hiding ( ByteString )
 import           Data.CRC24Q
+import           Data.RTCM3.Extras
 import           Data.Word.Word24
 
 msgRTCM3Preamble :: Word8
@@ -27,29 +29,34 @@
 data Msg = Msg
   { _msgRTCM3Len     :: Word16
   , _msgRTCM3Payload :: !ByteString
+  , _msgRTCM3Crc     :: Word24
   } deriving ( Show, Read, Eq )
 
 $(makeLenses ''Msg)
 
 instance Binary Msg where
   get = do
-    _msgRTCM3Len <- B.runBitGet $ do
-      _reserved <- B.getWord16be 6
-      B.getWord16be 10
+    _msgRTCM3Len     <- getWord16be
     _msgRTCM3Payload <- getByteString $ fromIntegral _msgRTCM3Len
+    _msgRTCM3Crc     <- getWord24be
     return Msg {..}
 
   put Msg {..} = do
-    B.runBitPut $ do
-      B.putWord16be 6 0
-      B.putWord16be 10 _msgRTCM3Len
+    putWord16be _msgRTCM3Len
     putByteString _msgRTCM3Payload
+    putWord24be _msgRTCM3Crc
 
-checkCrc :: Msg -> Word24
-checkCrc msg =
-  crc24q $ runPut $ do
-    putWord8 msgRTCM3Preamble
-    put msg
+checkNum :: ByteString -> Word16
+checkNum payload =
+  flip runGet (fromStrict payload) $ B.runBitGet $
+    B.getWord16be 12
+
+checkCrc :: Word16 -> ByteString -> Word24
+checkCrc len payload =
+  crc24q $ toLazyByteString $
+    word8 msgRTCM3Preamble  <>
+    word16BE len            <>
+    byteString payload
 
 class Binary a => ToRTCM3 a where
   toRTCM3 :: a -> Msg
