Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created March 9, 2019 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hodzanassredin/43288726dd7fc76f831bc47856228617 to your computer and use it in GitHub Desktop.
Save hodzanassredin/43288726dd7fc76f831bc47856228617 to your computer and use it in GitHub Desktop.
GuidToSN prototype
open System
open System.Collections.Generic
open Force.Crc32
open System.Text
open Murmur
open HashLib
let check keys e name =
let hsahes = new HashSet<string>()
let stopWatch = System.Diagnostics.Stopwatch.StartNew()
let add_hash x = hsahes.Add(e(x)) |> not
let collisions = Array.filter add_hash keys |> Array.length
stopWatch.Stop()
printfn "%s %f sec %d collisions (%f %%)" name stopWatch.Elapsed.TotalSeconds collisions (double(collisions) / double(keys.Length)*100.0)
let baseChars = "abcdefghijklmnopqrstuvwxyz23456789".ToCharArray()
let intToString(value: int64 ) =
let mutable i = 8
let mutable value = value
let buffer = Array.create<char> i 'a'
let targetBase = int64(baseChars.Length)
while value > 0L do
i <- i - 1
buffer.[i] <- baseChars.[int(value % targetBase)]
value <- value / targetBase
new string(buffer)
let toString(bytes : byte[])=
let buffer = Array.zeroCreate<byte> 8
Array.Copy(bytes, buffer, if bytes.Length > 5 then 5 else bytes.Length)
let value = BitConverter.ToInt64(buffer,0)
intToString value
let keys gen = seq{
while true do
yield gen()
}
let E2 = new Crc32CAlgorithm()
let crc40c (key : Guid) =
let key = key.ToByteArray()
let buffer = Array.create 5 0uy
let hash32 = E2.ComputeHash(key)
Array.Copy(hash32, buffer, 4)
let hash32_2 = E2.ComputeHash(key.[0..8])
buffer.[4] <- hash32_2.[0]
buffer |> toString
let crc32c (key : Guid) = E2.ComputeHash(key.ToByteArray()) |> toString
let E = new Crc32Algorithm()
let crc32 (key : Guid) = E.ComputeHash(key.ToByteArray()) |> toString
let m32 = MurmurHash.Create32(managed=false); // returns a 128-bit algorithm using "unsafe" code with default seed
let murmur32 (key : Guid) = m32.ComputeHash(key.ToByteArray()) |> toString
let m128 = MurmurHash.Create128(managed=false); // returns a 128-bit algorithm using "unsafe" code with default seed
let murmur128 (key : Guid) =
let ba =m128.ComputeHash(key.ToByteArray())
ba |> toString
let E64 = HashFactory.Checksum.CreateCRC64(HashLib.Checksum.CRC64Polynomials.ECMA_182);
let crc64 (key : Guid) =
let ba =E64.ComputeBytes(key.ToByteArray())
ba.GetBytes() |> toString
let E64zeroISO = HashFactory.Checksum.CreateCRC64(HashLib.Checksum.CRC64Polynomials.ISO);
let crc64ISO (key : Guid) =
let ba =E64zeroISO.ComputeBytes(key.ToByteArray())
ba.GetBytes() |> toString
let sha256E = HashFactory.Crypto.CreateSHA256()
let sha256 (key : Guid) =
let ba =sha256E.ComputeBytes(key.ToByteArray())
ba.GetBytes() |> toString
let fnv = HashFactory.Hash64.CreateFNV1a();
let fnv1a (key : Guid) =
let ba =fnv.ComputeBytes(key.ToByteArray())
ba.GetBytes() |> toString
let checkGuidGen gen name =
let count = 15000000
let keysSeq = keys gen
printfn "checking %d keys generated by %s " count name
printfn "Keys sample"
for k in keysSeq |> Seq.take 10 do
printfn "%A" k
let keys = keysSeq |> Seq.take count |> Array.ofSeq
printfn "results:"
//check keys sha256 "sha256"
check keys crc40c "crc40c"
//check keys crc64ISO "crc64 ISO poly"
check keys crc64 "crc64 ECMA_182 poly"
//check keys crc32 "crc32"
//check keys crc32c "crc32c"
//check keys murmur32 "murmur32"
//check keys murmur128 "murmur128"
//check keys fnv1a "FNV1a(64)"
let generateComb() =
let guidArray = Guid.NewGuid().ToByteArray()
let baseDate = new DateTime(1900, 1, 1)
let now = DateTime.Now
// Get the days and milliseconds which will be used to build the byte string
let days = new TimeSpan(now.Ticks - baseDate.Ticks)
let msecs = now.TimeOfDay
// Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333
let daysArray = BitConverter.GetBytes(days.Days)
let msecsArray = BitConverter.GetBytes(int64 (msecs.TotalMilliseconds / 3.333333))
// Reverse the bytes to match SQL Servers ordering
Array.Reverse(daysArray)
Array.Reverse(msecsArray)
// Copy the bytes into the guid
Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2)
Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4)
new Guid(guidArray)
let mutable i = Array.create 16 0uy
let mutable rev = false
let rec incArr (arr:byte[]) index =
if -1 = index then ()
else arr.[index] <- arr.[index] + 1uy
if arr.[index] = 0uy then incArr arr (index-1)
else ()
let incrementalGenerator()=
incArr i 15
rev<- not rev
new Guid(if rev then i else Array.rev i)
[<EntryPoint>]
let main argv =
let mutable a = 0;
checkGuidGen incrementalGenerator "Incremental guids"
checkGuidGen Guid.NewGuid "Guid.NewGuid"
checkGuidGen generateComb "Comb guids"
Console.ReadLine() |> ignore
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment