module Network.HTTP.Base64
( encode
, decode
, chop72
, Octet
) where
import Data.Array (Array, array, (!))
import Data.Bits (shiftL, shiftR, (.&.), (.|.))
import Data.Char (chr, ord)
import Data.Word (Word8)
type Octet = Word8
encodeArray :: Array Int Char
encodeArray :: Array Int Char
encodeArray = (Int, Int) -> [(Int, Char)] -> Array Int Char
forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Int
0,Int
64)
[ (Int
0,Char
'A'), (Int
1,Char
'B'), (Int
2,Char
'C'), (Int
3,Char
'D'), (Int
4,Char
'E'), (Int
5,Char
'F')
, (Int
6,Char
'G'), (Int
7,Char
'H'), (Int
8,Char
'I'), (Int
9,Char
'J'), (Int
10,Char
'K'), (Int
11,Char
'L')
, (Int
12,Char
'M'), (Int
13,Char
'N'), (Int
14,Char
'O'), (Int
15,Char
'P'), (Int
16,Char
'Q'), (Int
17,Char
'R')
, (Int
18,Char
'S'), (Int
19,Char
'T'), (Int
20,Char
'U'), (Int
21,Char
'V'), (Int
22,Char
'W'), (Int
23,Char
'X')
, (Int
24,Char
'Y'), (Int
25,Char
'Z'), (Int
26,Char
'a'), (Int
27,Char
'b'), (Int
28,Char
'c'), (Int
29,Char
'd')
, (Int
30,Char
'e'), (Int
31,Char
'f'), (Int
32,Char
'g'), (Int
33,Char
'h'), (Int
34,Char
'i'), (Int
35,Char
'j')
, (Int
36,Char
'k'), (Int
37,Char
'l'), (Int
38,Char
'm'), (Int
39,Char
'n'), (Int
40,Char
'o'), (Int
41,Char
'p')
, (Int
42,Char
'q'), (Int
43,Char
'r'), (Int
44,Char
's'), (Int
45,Char
't'), (Int
46,Char
'u'), (Int
47,Char
'v')
, (Int
48,Char
'w'), (Int
49,Char
'x'), (Int
50,Char
'y'), (Int
51,Char
'z'), (Int
52,Char
'0'), (Int
53,Char
'1')
, (Int
54,Char
'2'), (Int
55,Char
'3'), (Int
56,Char
'4'), (Int
57,Char
'5'), (Int
58,Char
'6'), (Int
59,Char
'7')
, (Int
60,Char
'8'), (Int
61,Char
'9'), (Int
62,Char
'+'), (Int
63,Char
'/') ]
int4_char3 :: [Int] -> [Char]
int4_char3 :: [Int] -> [Char]
int4_char3 (Int
a:Int
b:Int
c:Int
d:[Int]
t) =
let n :: Int
n = (Int
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
b Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
c Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
d)
in (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff))
Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff))
Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff)) Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Int] -> [Char]
int4_char3 [Int]
t
int4_char3 [Int
a,Int
b,Int
c] =
let n :: Int
n = (Int
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
b Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
c Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
6)
in [ (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff))
, (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
8 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff)) ]
int4_char3 [Int
a,Int
b] =
let n :: Int
n = (Int
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
b Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
12)
in [ (Int -> Char
chr (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
16 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0xff)) ]
int4_char3 [Int
_] = [Char] -> [Char]
forall a. HasCallStack => [Char] -> a
error [Char]
"Network.HTTP.Base64.int4_char3: impossible number of Ints."
int4_char3 [] = []
char3_int4 :: [Char] -> [Int]
char3_int4 :: [Char] -> [Int]
char3_int4 (Char
a:Char
b:Char
c:[Char]
t)
= let n :: Int
n = (Char -> Int
ord Char
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
16 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Char -> Int
ord Char
b Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
8 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Char -> Int
ord Char
c)
in (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f) Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f) Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f) Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f) Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
char3_int4 [Char]
t
char3_int4 [Char
a,Char
b]
= let n :: Int
n = (Char -> Int
ord Char
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
16 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Char -> Int
ord Char
b Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
8)
in [ (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f)
, (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f)
, (Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
6 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f) ]
char3_int4 [Char
a]
= let n :: Int
n = (Char -> Int
ord Char
a Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
16)
in [(Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
18 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f),(Int
n Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
12 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3f)]
char3_int4 [] = []
enc1 :: Int -> Char
enc1 :: Int -> Char
enc1 Int
ch = Array Int Char
encodeArrayArray Int Char -> Int -> Char
forall i e. Ix i => Array i e -> i -> e
!Int
ch
chop72 :: String -> String
chop72 :: [Char] -> [Char]
chop72 [Char]
str = let ([Char]
bgn,[Char]
end) = Int -> [Char] -> ([Char], [Char])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
70 [Char]
str
in if [Char] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
end then [Char]
bgn else [Char]
"\r\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
chop72 [Char]
end
quadruplets :: [Char] -> [Char]
quadruplets :: [Char] -> [Char]
quadruplets (Char
a:Char
b:Char
c:Char
d:[Char]
t) = Char
aChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
bChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
cChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:Char
dChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char] -> [Char]
quadruplets [Char]
t
quadruplets [Char
a,Char
b,Char
c] = [Char
a,Char
b,Char
c,Char
'=']
quadruplets [Char
a,Char
b] = [Char
a,Char
b,Char
'=',Char
'=']
quadruplets [Char
_] = [Char] -> [Char]
forall a. HasCallStack => [Char] -> a
error [Char]
"Network.HTTP.Base64.quadruplets: impossible number of characters."
quadruplets [] = []
enc :: [Int] -> [Char]
enc :: [Int] -> [Char]
enc = [Char] -> [Char]
quadruplets ([Char] -> [Char]) -> ([Int] -> [Char]) -> [Int] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Char) -> [Int] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Char
enc1
dcd :: String -> [Int]
dcd :: [Char] -> [Int]
dcd [] = []
dcd (Char
h:[Char]
t)
| Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'Z' Bool -> Bool -> Bool
&& Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'A' = Char -> Int
ord Char
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'A' Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
dcd [Char]
t
| Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'0' Bool -> Bool -> Bool
&& Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'9' = Char -> Int
ord Char
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
52 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
dcd [Char]
t
| Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
>= Char
'a' Bool -> Bool -> Bool
&& Char
h Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'z' = Char -> Int
ord Char
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'a' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
26 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
dcd [Char]
t
| Char
h Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'+' = Int
62 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
dcd [Char]
t
| Char
h Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/' = Int
63 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: [Char] -> [Int]
dcd [Char]
t
| Char
h Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'=' = []
| Bool
otherwise = [Char] -> [Int]
dcd [Char]
t
encode :: [Octet] -> String
encode :: [Octet] -> [Char]
encode = [Int] -> [Char]
enc ([Int] -> [Char]) -> ([Octet] -> [Int]) -> [Octet] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Int]
char3_int4 ([Char] -> [Int]) -> ([Octet] -> [Char]) -> [Octet] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Octet -> Char) -> [Octet] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
chr (Int -> Char) -> (Octet -> Int) -> Octet -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Octet -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral))
decode :: String -> [Octet]
decode :: [Char] -> [Octet]
decode = ((Char -> Octet) -> [Char] -> [Octet]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Octet
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Octet) -> (Char -> Int) -> Char -> Octet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord)) ([Char] -> [Octet]) -> ([Char] -> [Char]) -> [Char] -> [Octet]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Char]
int4_char3 ([Int] -> [Char]) -> ([Char] -> [Int]) -> [Char] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Int]
dcd