Advertisement
Guest User

Untitled

a guest
Jun 29th, 2016
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.89 KB | None | 0 0
  1. module tinyBase64Decoder
  2. open System
  3. open System.Text
  4. open System.Collections.Generic
  5.  
  6. // Declare fundamental functions
  7.  
  8. // Generate n length Integer List (0 upto n - 1)
  9. let iota n = [0..n-1] |> List.map (fun i -> i)
  10.  
  11. // Generate n length List of x
  12. let repeat n x = iota n |> List.map (fun _ -> x)
  13.  
  14. // Convert binary string into decimal
  15. let binToDec binStr = Convert.ToInt32 (binStr, 2)
  16.  
  17. // Convert decimal into binary string
  18. let decToBin dec = Convert.ToString (dec &&& 0xff, 2)
  19.  
  20. // Convert Char Sequence into String
  21. let charSeqToString charSeq =
  22. let charList = charSeq |> Seq.toList
  23. in string (List.fold (fun (sb:StringBuilder) (c:char) -> sb.Append(c))
  24. (new StringBuilder())
  25. charList)
  26.  
  27. // Convert int List (corresponding with char) into String
  28. let intListToString intList =
  29. intList
  30. |> List.map (fun x -> char x |> string)
  31. |> String.concat ""
  32.  
  33. // BASE64 Decoder and Subsets
  34.  
  35. // Base64 Charactors
  36. let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |> Seq.toList
  37.  
  38. // Conversion table, Base64 Char to Binary number string
  39. let table =
  40. let tableValues =
  41. iota(charset.Length)
  42. |> List.map decToBin
  43. |> List.map (fun e -> if e.Length = 6 then e else (repeat (6 - e.Length) "0" |> String.concat "") + e)
  44.  
  45. let dic = new Dictionary<char, string>()
  46. in
  47. Seq.zip charset tableValues
  48. |> Seq.iter(fun (key, value) -> dic.Add(key, value))
  49. dic
  50.  
  51. // Convert Base64 strings into Binary String(by replacing with the above table)
  52. let convert data =
  53. data |> Seq.filter (fun x -> x <> '=')
  54. |> Seq.map (fun e-> table.[e])
  55. |> String.Concat
  56.  
  57.  
  58. // Create List by 4 bits List from convted string
  59. let getQuotients (converted:string) =
  60. let cLen = converted.Length
  61. in
  62. iota (cLen / 4)
  63. |> List.map (fun i -> converted.[(i * 4)..((i + 1) * 4 - 1)])
  64.  
  65. // Create List by two bits List from ```quotients``` (require it from result of the above function)
  66. let getBuffers quotients =
  67. let quotients = List.toArray quotients
  68. let qLen = quotients.Length
  69. in
  70. iota(qLen / 2)
  71. |> List.map (fun i -> quotients.[(i * 2)..((i + 1) * 2 - 1)])
  72.  
  73. // Generating Binaries with buffers from the above function
  74. let finalize buf =
  75. buf |> List.map (fun (b:string[]) ->
  76. let b0 = b.[0] |> binToDec
  77. let b1 = b.[1] |> binToDec
  78. ((b0 <<< 4) ^^^ b1) &&& 0xff)
  79.  
  80. // Decode base64 String into Unsinged Bytes
  81. let decode64 (data:string) =
  82. data
  83. |> convert
  84. |> getQuotients
  85. |> getBuffers
  86. |> finalize
  87.  
  88. //Decode Test. The below codes are test for decoding
  89. let encoded = "QUJDREVGRw==" // <- encoded string of "ABCDEFG"
  90. assert ("ABCDEFG" = (decode64 encoded |> intListToString))
  91. printfn "%s -> %A" encoded <| (decode64 encoded |> intListToString)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement