Мне нужно преобразовать ByteString в список из 7 бит байтов. Например, байты с A, B, C, D и т.д. битов:Преобразование байтовой строки в список из 7 бит байтов
abcdefgh ijklmnop qrstuvwx yz...
должны быть преобразованы в:
abcdefg hijklmn opqrstu vwxyz...
Я использую пакет двоичных бита для того, чтобы сделать это. Моя функция convert8to7
является рекурсивной, но двоичные биты не предоставляют никакого значения для проверки отсутствия бит, тогда как монада Get
имеет isEmpty
или remaining
.
Вот мой код:
import Data.Word
import Data.Binary.Bits.Get
import Data.Binary.Get (runGet)
import Data.ByteString.Lazy.Char8
convert8to7 :: BitGet [Word8]
convert8to7 = do
bits <- getWord8 7
rest <- convert8to7
return (bits : rest)
main :: IO()
main = do
let datas = pack "Hello world!"
print $ runGet (runBitGet convert8to7) datas
Когда я запускаю этот код, он логически говорит:
Data.Binary.Get.runGet at position 12: demandInput: not enough bytes
Могу ли я сделать это преобразование с двоичными битами, или я должен искать другой пакет?
Update
Вот мой код, основанный на user5402 ответ:
import Data.Word
import Data.Bits
import Data.Binary.Bits.Get
import Data.Binary.Get (runGet)
import qualified Data.ByteString.Lazy.Char8 as BS
convert87 :: Int -> BitGet [Word8]
convert87 n
| n == 0 = return []
| n < 7 = do bits <- getWord8 n
return [shiftL bits (7 - n)]
| otherwise = do bits <- getWord8 7
rest <- convert87 (n-7)
return $ bits : rest
to87 :: BS.ByteString -> [Word8]
to87 datas = runGet (runBitGet (convert87 len)) datas
where len = fromIntegral $ BS.length datas * 8
main :: IO()
main = do
let datas = BS.pack "Hello world!"
print $ to87 datas
Версия Binary-Bits для взлома очень устарела. С 1 апреля 2003 года у Github был 'isEmpty :: BitGet Bool'. –
Хотя он устарел, я буду придерживаться версии, предоставляемой хакером. Во-первых, это будет легче поддерживать, во-вторых, функция 'isEmpty' не позволяет мне обрабатывать случай, когда бит не хватает для формирования 7-битного байта. Спасибо – zigazou
Достаточно честный. В структуре «BitGet» нет ничего, что помешало бы добавить функцию, которая делает именно то, что вы хотите, но в очередной раз это не будет в хаке. Увидев пакет взлома, который устарел, я все еще задавался вопросом: есть ли у них процедура захвата заброшенных проектов? –