0 people like it.

Decode Base36 in F#

I couldn't fine a reasonably fast or good (yuck floats) implementation anywhere so I wrote one. All of the error checking does slow it down and should be ideally done up front.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
open System
let decodeBase36 (input: string) = 
    if String.IsNullOrEmpty(input) then
        raise (new ArgumentException("decodeBase36 input string was null or empty"))
    
    let zeroChar = uint64 '0' // int 48
    let lowPunc  = uint64 ':' // int 58
    let highPunc = uint64 '@' // int 64
    let maxChar  = uint64 'Z' // int 90

    let mutable result = 0UL
    let mutable expBase = 1UL

    for i = input.Length - 1 downto 0 do
        let cv = 
            let c = uint64 input.[i] 
            if (c >= lowPunc && c <= highPunc) || c < zeroChar || c > maxChar then
                raise (new ArgumentException(sprintf "decodeBase36 found an unexpected character in string: %c" input.[i]))
            let v = c - zeroChar
            if v > 10UL then v - 7UL else v   
        
        result <- result + (cv * expBase)
        expBase <- expBase * 36UL
   
    result
namespace System
val decodeBase36 : input:string -> uint64

Full name: Script.decodeBase36
val input : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
String.IsNullOrEmpty(value: string) : bool
val raise : exn:Exception -> 'T

Full name: Microsoft.FSharp.Core.Operators.raise
Multiple items
type ArgumentException =
  inherit SystemException
  new : unit -> ArgumentException + 4 overloads
  member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
  member Message : string
  member ParamName : string

Full name: System.ArgumentException

--------------------
ArgumentException() : unit
ArgumentException(message: string) : unit
ArgumentException(message: string, innerException: exn) : unit
ArgumentException(message: string, paramName: string) : unit
ArgumentException(message: string, paramName: string, innerException: exn) : unit
val zeroChar : uint64
Multiple items
val uint64 : value:'T -> uint64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.uint64

--------------------
type uint64 = UInt64

Full name: Microsoft.FSharp.Core.uint64
val lowPunc : uint64
val highPunc : uint64
val maxChar : uint64
val mutable result : uint64
val mutable expBase : uint64
val i : int
property String.Length: int
val cv : uint64
val c : uint64
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val v : uint64
Raw view Test code New version

More information

Link:http://fssnip.net/7Uu
Posted:6 years ago
Author:Rick Minerich
Tags: encoding , base36