Last active
June 29, 2016 23:25
-
-
Save alphaKAI/8d10cba0444e4f3c1ddf7d34e0696b1e to your computer and use it in GitHub Desktop.
Tiny Base64 Decoder in F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module tinyBase64Decoder | |
open System | |
open System.Collections.Generic | |
// Declare fundamental functions | |
// 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 = Array.ofSeq charSeq |> Seq.map string |> String.concat "" | |
// Convert int List (corresponding with char) into String | |
let intListToString intList = | |
intList | |
|> List.map char | |
|> charSeqToString | |
// BASE64 Decoder and Subsets | |
// Base64 Charactors | |
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |> Seq.toList | |
// Conversion table, Base64 Char to Binary number string | |
let table = | |
charset | |
|> List.mapi (fun i c -> | |
let e = decToBin i | |
let s = String.replicate (6 - e.Length) "0" + e | |
c, s) | |
|> Map.ofList | |
// Convert Base64 strings into Binary String(by replacing with the above table) | |
let convert data = | |
data | |
|> Seq.choose (fun e -> Map.tryFind e table) | |
|> String.concat "" | |
// Create List by 4 bits List from convted string | |
let getQuotients (converted:string) = | |
let cLen = converted.Length | |
List.init (cLen / 4) (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 | |
List.init (qLen / 2) (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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment