2012-07-08 32 views
5

Tôi đang triển khai giao thức quy định rằng một chuỗi biểu thị mật khẩu phải được tuần tự hóa thành trường có độ dài cố định, 10 byte. Tôi đang sử dụng Data.Cereal để thực hiện nhiệm vụ này. Dưới đây là đi gần đây nhất của tôi lúc đó:Nối tiếp chuỗi ký tự với Data.Cereal hoặc Data.Binary

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

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

đặt trên ByteStrings prepends thêm một đoạn 8-byte vào phía trước của những gì nó được mã hóa làm:

runPut $ putPassword "Friend" 

kết quả trong:

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

Tôi không muốn đoạn thừa. Tại sao lại hành xử theo cách này?

Có ai biết cách tuần tự hóa chỉ 10 byte gốc không?

Trả lời

7

Tôi giả định bởi "đoạn thừa", nghĩa là bit đầu tiên của "\NUL\NUL\NUL\NUL\NUL\NUL\NUL\n. Đó là trường có độ dài 64 bit (chú ý giá trị của nó là 10) là một phần của định nghĩa Nối tiếp cho ByteString. Vì bạn đã có quyền kiểm tra sau khi gọi TE.encodeUtf8, tôi khuyên bạn chỉ nên sử dụng putByteString để tránh trường độ dài (hoặc putLazyByteString nếu bạn đang nhập mô-đun mã hóa văn bản lười).

2

Như Thomas đã nêu put trên ByteStrings sẽ thêm độ dài được mã hóa. Được hiển thị bên dưới là ví dụ thực tế:

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

putByteString một mình thì không. Giải pháp là sử dụng putByteString:

putPassword :: Putter Password 
putPassword = putByteString . TE.encodeUtf8 . padText 10 
Các vấn đề liên quan