using System.Security.Cryptography;
static void Main(string[] args)
private static void Test64()
for (int i = 0; i < 100_000_000; i++)
if (ComputeFeatureValue64(Guid.NewGuid().ToString()) == 0)
Console.WriteLine($"64bit: a: {a}, b:{b}");
private static void Test128()
for (int i = 0; i < 100_000_000; i++)
if (ComputeFeatureValue(Guid.NewGuid().ToString()) == 0)
Console.WriteLine($"128bit: a: {a}, b:{b}");
private static readonly ThreadLocal<MD5> ThreadMd5 = new ThreadLocal<MD5>(MD5.Create);
private static int ComputeFeatureValue64(string userId)
var input = $"{userId}123";
var inputHash = ThreadMd5.Value.ComputeHash(Encoding.UTF8.GetBytes(input));
var featureValue = (byte)BigInteger.Abs(new BigInteger(inputHash) % new BigInteger(100) + 1);
return featureValue > 50 ? 0 : 1;
private static byte ComputeFeatureValue(string userId)
var input = $"{userId}123";
var inputHash = ThreadMd5.Value.ComputeHash(Encoding.UTF8.GetBytes(input));
var featureValue = (float)(new BigInteger(inputHash, true) % 100);
return featureValue + 1f > 50 ? (byte)0 : (byte)1;