Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module tinyBase64Decoder
- open System
- open System.Text
- open System.Collections.Generic
- // Declare fundamental functions
- // Generate n length Integer List (0 upto n - 1)
- let iota n = [0..n-1] |> List.map (fun i -> i)
- // Generate n length List of x
- let repeat n x = iota n |> List.map (fun _ -> x)
- // Convert binary string into decimal
- let binToDec binStr = Convert.ToInt32 (binStr, 2)
- // Convert decimal into binary string
- let decToBin dec = Convert.ToString (dec &&& 0xff, 2)
- // Convert Char Sequence into String
- let charSeqToString charSeq =
- let charList = charSeq |> Seq.toList
- in string (List.fold (fun (sb:StringBuilder) (c:char) -> sb.Append(c))
- (new StringBuilder())
- charList)
- // Convert int List (corresponding with char) into String
- let intListToString intList =
- intList
- |> List.map (fun x -> char x |> string)
- |> String.concat ""
- // BASE64 Decoder and Subsets
- // Base64 Charactors
- let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |> Seq.toList
- // Conversion table, Base64 Char to Binary number string
- let table =
- let tableValues =
- iota(charset.Length)
- |> List.map decToBin
- |> List.map (fun e -> if e.Length = 6 then e else (repeat (6 - e.Length) "0" |> String.concat "") + e)
- let dic = new Dictionary<char, string>()
- in
- Seq.zip charset tableValues
- |> Seq.iter(fun (key, value) -> dic.Add(key, value))
- dic
- // Convert Base64 strings into Binary String(by replacing with the above table)
- let convert data =
- data |> Seq.filter (fun x -> x <> '=')
- |> Seq.map (fun e-> table.[e])
- |> String.Concat
- // Create List by 4 bits List from convted string
- let getQuotients (converted:string) =
- let cLen = converted.Length
- in
- iota (cLen / 4)
- |> List.map (fun i -> converted.[(i * 4)..((i + 1) * 4 - 1)])
- // Create List by two bits List from ```quotients``` (require it from result of the above function)
- let getBuffers quotients =
- let quotients = List.toArray quotients
- let qLen = quotients.Length
- in
- iota(qLen / 2)
- |> List.map (fun i -> quotients.[(i * 2)..((i + 1) * 2 - 1)])
- // Generating Binaries with buffers from the above function
- let finalize buf =
- buf |> List.map (fun (b:string[]) ->
- let b0 = b.[0] |> binToDec
- let b1 = b.[1] |> binToDec
- ((b0 <<< 4) ^^^ b1) &&& 0xff)
- // Decode base64 String into Unsinged Bytes
- let decode64 (data:string) =
- data
- |> convert
- |> getQuotients
- |> getBuffers
- |> finalize
- //Decode Test. The below codes are test for decoding
- let encoded = "QUJDREVGRw==" // <- encoded string of "ABCDEFG"
- assert ("ABCDEFG" = (decode64 encoded |> intListToString))
- printfn "%s -> %A" encoded <| (decode64 encoded |> intListToString)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement