2012-07-08 109 views
5

我正在實現一個協議,該協議規定表示密碼的字符串應串行化爲固定長度的10字節字段。我正在使用Data.Cereal來執行此任務。這是我最近去吧:使用Data.Cereal或Data.Binary對字符串進行序列化

padText :: Int -> Text -> Text 
padText fieldLen = T.justifyLeft fieldLen '\NUL' 

putPassword :: Putter Password 
putPassword = put . TE.encodeUtf8 . padText 10 

穿上字節串前添加一個額外的8字節塊到它是什麼編碼製作的面前:

runPut $ putPassword "Friend" 

結果:

"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\nFriend\NUL\NUL\NUL\NUL" 

我不想要額外的塊。爲什麼這樣表現?

有誰知道如何只序列化10個原始字節?

回答

7

我認爲「額外的塊」是指"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\n的第一位。這是一個64位長的字段(注意它的值是10),它是ByteString的序列化定義的一部分。由於您在調用TE.encodeUtf8後已經有了一個字節串,我建議您只使用putByteString來避免長度字段(或者如果您導入惰性文本編碼模塊,則使用putLazyByteString)。

2

正如Thomas在ByteStrings上所說的put預先編碼的長度。如下圖所示 是實際的實例:

instance Serialize B.ByteString where 
    put bs = do put (B.length bs :: Int) 
       putByteString bs 
    ... 

單獨putByteString沒有。解決方案是使用putByteString

putPassword :: Putter Password 
putPassword = putByteString . TE.encodeUtf8 . padText 10 
相關問題