2012-07-08 1 views
5

암호를 나타내는 문자열을 고정 길이의 10 바이트 필드로 serialize해야한다는 프로토콜을 구현하고 있습니다. 이 작업을 수행하기 위해 Data.Cereal을 사용하고 있습니다. 여기에 나의 가장 최근의 이동이다 :Data.Cereal 또는 Data.Binary를 사용하여 문자열 직렬화

runPut $ putPassword "Friend" 

결과에 :

"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\nFriend\NUL\NUL\NUL\NUL" 
ByteStrings에

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

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

넣어 그것을 만드는 인코딩 무엇의 전면에 추가로 8 바이트 덩어리를 앞에 추가

여분의 청크가 필요하지 않습니다. 왜 이런 식으로 행동합니까?

누구나 원래의 10 바이트 만 직렬화하는 방법을 알고 있습니까?

답변

7

"여분의 덩어리"로 가정 할 때 첫 번째 비트는 "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\n입니다. 그것은 ByteString에 대한 Serialize 정의의 일부인 64 비트 길이 필드입니다 (값은 10입니다). TE.encodeUtf8을 호출 한 후 이미 자막을 작성 했으므로 길이 필드를 피하려면 putByteString을 사용하는 것이 좋습니다 (지연 문자 인코딩 모듈을 가져 오는 경우 putLazyByteString).

2

By 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 
관련 문제