import Data.List (elemIndex, foldr1) import Data.Maybe (catMaybes) import Data.Encoding (encodeString) import Data.Encoding.CP1251 import Data.Char (ord, toUpper) import Data.Bits (xor) import Numeric (showHex) import Data.Function (on) -------------------------------------------------- -------------------------------------------------- -- Util -------------------------------------------------- -------------------------------------------------- getMsg :: String -> [Int] getMsg = map ord . encodeString CP1251 intBits :: Int -> Int -> [Bool] intBits 0 0 = [] intBits 0 _ = error "Integer larger than expected" intBits n i = let (d, m) = i `divMod` 2 in intBits (n - 1) d ++ [m == 1] cp1251bits :: [Int] -> [Bool] cp1251bits = (=<<) $ intBits 8 hexIntShow :: Int -> String hexIntShow = map toUpper . flip showHex "" uniq :: Eq a => [a] -> [a] uniq [] = [] uniq (a : as) = case uniq as of [] -> [a] (b : bs) -> if a == b then b : bs else a : b : bs bitToInt :: Bool -> Int bitToInt False = 0 bitToInt True = 1 -------------------------------------------------- -------------------------------------------------- -- Encodings -------------------------------------------------- -------------------------------------------------- class BitEncoding a where encode :: a -> [Bool] -> [Int] class TwoLevelEncoding a where tlEncode :: a -> [Bool] -> [Bool] -- NRZ data NRZ = NRZ instance TwoLevelEncoding NRZ where tlEncode _ = id instance BitEncoding NRZ where encode m = map bitToInt . tlEncode m -- RZ data RZ = RZ instance BitEncoding RZ where encode _ = (=<<) (\b -> if b then [2, 1] else [0, 1]) -- AMI data AMI = AMI instance BitEncoding AMI where encode _ = let encode' _ [] = [] encode' dir (b : bs) = if b then (if dir then 2 else 0) : encode' (not dir) bs else 1 : encode' dir bs in encode' True -- NRZI data NRZI = NRZI instance TwoLevelEncoding NRZI where tlEncode _ = let encode' _ [] = [] encode' p (b : bs) = if b then not p : encode' (not p) bs else p : encode' p bs in encode' False instance BitEncoding NRZI where encode m = map bitToInt . tlEncode m -- Manchester data Manchester = Manchester instance TwoLevelEncoding Manchester where tlEncode _ = (=<<) (\b -> if b then [True, False] else [False, True]) instance BitEncoding Manchester where encode m = map bitToInt . tlEncode m -- DiffManchester data DiffManchester = DiffManchester instance TwoLevelEncoding DiffManchester where tlEncode m = tlEncode' True where tlEncode' p [] = [] tlEncode' p (b : bs) = if b then p : not p : tlEncode' (not p) bs else not p : p : tlEncode' p bs instance BitEncoding DiffManchester where encode m = map bitToInt . tlEncode m -- MLT3 data MLT3 = MLT3 instance BitEncoding MLT3 where encode m bs = encode' 1 True bs where encode' _ _ [] = [] encode' p up (b : bs) = if b then case p of 0 -> 1 : encode' 1 True bs 1 -> if up then 2 : encode' 2 up bs else 0 : encode' 0 up bs 2 -> 1 : encode' 1 False bs else p : encode' p up bs -- PAM5 data PAM5 = PAM5 instance BitEncoding PAM5 where encode _ [] = [] encode m (b1 : b2 : bs) = (2 * bitToInt b1) + (bitToInt b2) : encode m bs -- 4B5B data Encoding4B5B = Encoding4B5B instance TwoLevelEncoding Encoding4B5B where tlEncode _ [] = [] tlEncode e (b0 : b1 : b2 : b3 : bs) = (case (b0, b1, b2, b3) of (False, False, False, False) -> [True , True , True , True , False] (False, False, False, True ) -> [False, True , False, False, True ] (False, False, True , False) -> [True , False, True , False, False] (False, False, True , True ) -> [True , False, True , False, True ] (False, True , False, False) -> [False, True , False, True , False] (False, True , False, True ) -> [False, True , False, True , True ] (False, True , True , False) -> [False, True , True , True , False] (False, True , True , True ) -> [False, True , True , True , True ] (True , False, False, False) -> [True , False, False, True , False] (True , False, False, True ) -> [True , False, False, True , True ] (True , False, True , False) -> [True , False, True , True , False] (True , False, True , True ) -> [True , False, True , True , True ] (True , True , False, False) -> [True , True , False, True , False] (True , True , False, True ) -> [True , True , False, True , True ] (True , True , True , False) -> [True , True , True , False, False] (True , True , True , True ) -> [True , True , True , False, True ] ) ++ tlEncode e bs instance BitEncoding Encoding4B5B where encode m = map bitToInt . tlEncode m -- Scrambling data Scrambling = Scrambling [Int] instance TwoLevelEncoding Scrambling where tlEncode (Scrambling ns) bs = tlEncode' [] bs where tlEncode' _ [] = [] tlEncode' old (b : bs) = let olds = map ((!!) old . pred) $ filter (length old >=) ns nv = foldr1 xor (b : olds) in nv : tlEncode' (nv : old) bs instance BitEncoding Scrambling where encode m = map bitToInt . tlEncode m -------------------------------------------------- -------------------------------------------------- -- Fourier -------------------------------------------------- -------------------------------------------------- type Ampl = Double type Freq = Double data AmplFreq = AmplFreq { ampl :: Ampl, freq :: Double } deriving (Show, Eq) signalSpectre :: Ampl -> [AmplFreq] -> [AmplFreq] signalSpectre a = let ap = a / sqrt 2 in takeWhile ((< ap) . ampl) . dropWhile ((< ap) . ampl) . take 160000 fourier :: Double -> [Double] -> [AmplFreq] fourier len pts = map f [1 .. ] where f n = let sp = zip pts [0 .. ] freq = pi * n / len ampl = (*) (2 / len) . sum . map k $ pts k = const 0 in AmplFreq ampl freq