Created
March 9, 2019 18:20
-
-
Save hodzanassredin/43288726dd7fc76f831bc47856228617 to your computer and use it in GitHub Desktop.
GuidToSN prototype
This file contains hidden or 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
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