diff options
author | Stephen Paul Weber <singpolyma@singpolyma.net> | 2012-09-11 11:34:49 -0500 |
---|---|---|
committer | Stephen Paul Weber <singpolyma@singpolyma.net> | 2012-09-11 11:34:49 -0500 |
commit | a595481760fe5c4dc2e970a3a164ac12d4005d73 (patch) | |
tree | 927efcc32372ff4697a469149159b782f2c3d692 | |
parent | 2be234f7a2db4880ea7f66c58d93539c18ddc81e (diff) |
Better bit counting. Handle the bitlength of 0
Closes #17
-rw-r--r-- | Data/OpenPGP.hs | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/Data/OpenPGP.hs b/Data/OpenPGP.hs index 70bd29a..a268dff 100644 --- a/Data/OpenPGP.hs +++ b/Data/OpenPGP.hs | |||
@@ -62,6 +62,7 @@ module Data.OpenPGP ( | |||
62 | 62 | ||
63 | import Numeric | 63 | import Numeric |
64 | import Control.Monad | 64 | import Control.Monad |
65 | import Control.Arrow | ||
65 | import Control.Exception (assert) | 66 | import Control.Exception (assert) |
66 | import Data.Bits | 67 | import Data.Bits |
67 | import Data.Word | 68 | import Data.Word |
@@ -790,19 +791,23 @@ signatures_and_data (Message lst) = | |||
790 | newtype MPI = MPI Integer deriving (Show, Read, Eq, Ord) | 791 | newtype MPI = MPI Integer deriving (Show, Read, Eq, Ord) |
791 | instance BINARY_CLASS MPI where | 792 | instance BINARY_CLASS MPI where |
792 | put (MPI i) = do | 793 | put (MPI i) = do |
793 | put (((fromIntegral . B.length $ bytes) - 1) * 8 | 794 | put (bitl :: Word16) |
794 | + floor (logBase (2::Double) $ fromIntegral (bytes `B.index` 0)) | ||
795 | + 1 :: Word16) | ||
796 | putSomeByteString bytes | 795 | putSomeByteString bytes |
797 | where | 796 | where |
798 | bytes = if B.null bytes' then B.singleton 0 else bytes' | 797 | (bytes, bitl) |
798 | | B.null bytes' = (B.singleton 0, 1) | ||
799 | | otherwise = | ||
800 | (bytes', (fromIntegral (B.length bytes') - 1) * 8 + sigBit) | ||
801 | |||
802 | sigBit = fst $ until ((==0) . snd) | ||
803 | (first (+1) . second (`shiftR` 1)) (0,B.index bytes 0) | ||
799 | bytes' = B.reverse $ B.unfoldr (\x -> | 804 | bytes' = B.reverse $ B.unfoldr (\x -> |
800 | if x == 0 then Nothing else | 805 | if x == 0 then Nothing else |
801 | Just (fromIntegral x, x `shiftR` 8) | 806 | Just (fromIntegral x, x `shiftR` 8) |
802 | ) (assertProp (>=0) i) | 807 | ) (assertProp (>=0) i) |
803 | get = do | 808 | get = do |
804 | length <- fmap fromIntegral (get :: Get Word16) | 809 | length <- fmap fromIntegral (get :: Get Word16) |
805 | bytes <- getSomeByteString ((length + 7) `div` 8) | 810 | bytes <- getSomeByteString (assertProp (>0) $ (length + 7) `div` 8) |
806 | return (MPI (B.foldl (\a b -> | 811 | return (MPI (B.foldl (\a b -> |
807 | a `shiftL` 8 .|. fromIntegral b) 0 bytes)) | 812 | a `shiftL` 8 .|. fromIntegral b) 0 bytes)) |
808 | 813 | ||