module Codec.Binary.BubbleBabble(encode) where


import Data.Array.Unboxed
import Data.Bits
import Data.Word

import Codec.Utils


vowel :: UArray Int Char
vowel :: UArray Int Char
vowel = forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Int
0,Int
5) String
"aeiouy"

consonant :: UArray Int Char
consonant :: UArray Int Char
consonant = forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
(i, i) -> [e] -> a i e
listArray (Int
0,Int
16) String
"bcdfghklmnprstvzx"


-- | Encode binary data into the /Bubble Babble/ human readable encoding.
-- /Bubble Babble/ is an encoding that represents binary data as psuedowords
-- which are more pronouncable and memorable than standard hexadecimal encoding.
--
-- It is mainly used for representing cryptographic fingerprints.
-- In addition, there is an amount of redundancy and error correction built into
-- the representation so that transcription errors can be more readily identified.
--
-- See also <http://web.mit.edu/kenta/www/one/bubblebabble/spec/jrtrjwzi/draft-huima-01.txt "The Bubble Babble Binary Data Encoding" specification> for more details.

encode :: [Octet] -> String
encode :: [Octet] -> String
encode [Octet]
cs = Char
'x' forall a. a -> [a] -> [a]
: Int -> [Int] -> String
bb Int
1 (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (Integral a, Num b) => a -> b
fromIntegral [Octet]
cs) where
    bb :: Int -> [Int] -> String
bb Int
seed [] = (Int, Int, Int) -> String
vcvx  ((Int
seed forall a. Integral a => a -> a -> a
`mod` Int
6),Int
16,(Int
seed forall a. Integral a => a -> a -> a
`div` Int
6))
    bb Int
seed [Int
x] = (Int, Int, Int) -> String
vcvx ((((Int
x forall a. Bits a => a -> Int -> a
`shiftR` Int
6) forall a. Bits a => a -> a -> a
.&. Int
3) forall a. Num a => a -> a -> a
+ Int
seed) forall a. Integral a => a -> a -> a
`mod` Int
6, (Int
x forall a. Bits a => a -> Int -> a
`shiftR` Int
2) forall a. Bits a => a -> a -> a
.&. Int
15, ((Int
x forall a. Bits a => a -> a -> a
.&. Int
3) forall a. Num a => a -> a -> a
+ (Int
seed forall a. Integral a => a -> a -> a
`div` Int
6)) forall a. Integral a => a -> a -> a
`mod` Int
6)
    bb Int
seed (Int
x:Int
y:[Int]
xs) = (Int, Int, Int, Int, Int) -> String -> String
vcvcc (Int
a,Int
b,Int
c,Int
d,Int
e) forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> String
bb ((Int
seed forall a. Num a => a -> a -> a
* Int
5 forall a. Num a => a -> a -> a
+ (Int
x forall a. Num a => a -> a -> a
* Int
7 forall a. Num a => a -> a -> a
+ Int
y)) forall a. Integral a => a -> a -> a
`mod` Int
36) [Int]
xs where
        a :: Int
a = (((Int
x forall a. Bits a => a -> Int -> a
`shiftR` Int
6) forall a. Bits a => a -> a -> a
.&. Int
3) forall a. Num a => a -> a -> a
+ Int
seed) forall a. Integral a => a -> a -> a
`mod` Int
6
        b :: Int
b = (Int
x forall a. Bits a => a -> Int -> a
`shiftR` Int
2) forall a. Bits a => a -> a -> a
.&. Int
15
        c :: Int
c = ((Int
x forall a. Bits a => a -> a -> a
.&. Int
3) forall a. Num a => a -> a -> a
+ (Int
seed forall a. Integral a => a -> a -> a
`div` Int
6)) forall a. Integral a => a -> a -> a
`mod` Int
6
        d :: Int
d = (Int
y forall a. Bits a => a -> Int -> a
`shiftR` Int
4) forall a. Bits a => a -> a -> a
.&. Int
15
        e :: Int
e = Int
y forall a. Bits a => a -> a -> a
.&. Int
15
    vcvx :: (Int, Int, Int) -> String
vcvx (Int
a,Int
b,Int
c) = UArray Int Char
vowelforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
a forall a. a -> [a] -> [a]
: UArray Int Char
consonantforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
b forall a. a -> [a] -> [a]
: UArray Int Char
vowelforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
c forall a. a -> [a] -> [a]
: String
"x"
    vcvcc :: (Int, Int, Int, Int, Int) -> String -> String
vcvcc (Int
a,Int
b,Int
c,Int
d,Int
e) String
xs =  UArray Int Char
vowelforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
a forall a. a -> [a] -> [a]
: UArray Int Char
consonantforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
b forall a. a -> [a] -> [a]
: UArray Int Char
vowelforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
c forall a. a -> [a] -> [a]
: UArray Int Char
consonantforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
d forall a. a -> [a] -> [a]
: Char
'-' forall a. a -> [a] -> [a]
: UArray Int Char
consonantforall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Int
e forall a. a -> [a] -> [a]
: String
xs