Reputation: 4759
I've a situation to create a 16 digit number from another integer. It should be like a credit card number. So what is our scenario is if that users ID is 1 or 2, that should be hashed to a 16 digit string (Numeric). So that 16 digit should be unique for 1 I tried to .NET builtin functions like generate hash etc.
That doesn't helped me for a perfect solution
Upvotes: 2
Views: 1198
Reputation: 39329
Maybe you could use this:
string SixteenDigitHash(int value)
{
var rnd = new Random(value);
StringBuilder sb = new StringBuilder(16);
sb.Append(rnd.Next(1,10)); // first digit 1..9
for (int i=1; i<16; i++)
{
sb.Append(rnd.Next(0,10)); // other digits 0..9
}
return sb.ToString();
}
It uses Random
to generate (pseudo) random numbers, but uses the value-to-hash as seed so it always generates the same sequence for a given value and different sequences for different values.
One problem: the sequence is not guaranteed to be the same for different versions of the framework. Maybe you should use your own implementation of that Random class so that you know that the sequence is stable.
Upvotes: 1
Reputation: 6948
Not sure how many users you expect, but this code produces 16 digit integers and using the numbers from 1 to 100 there were no repeats:
Imports System.Security.Cryptography
Dim sha As New SHA1CryptoServiceProvider()
Dim IntList As New List(Of ULong)
For I = 1 To 100000
'Need a byte array for the ComputeHash method
Dim data() As Byte = BitConverter.GetBytes(I)
If BitConverter.IsLittleEndian Then Array.Reverse(data)
'Store the 160 bit hash in a byte array
Dim result As Byte() = sha.ComputeHash(data)
'Bitconverter's result can be too long, so by taking the first 16 digits _
of the results that are too long, and padding the rest to the right with _
0's we end up with unique 16 digit integers
Dim HashInt As ULong = ULong.Parse(BitConverter.ToUInt64(result, 0).ToString.PadRight(16, "0"c).Substring(0, 16))
'Using a list to hold the hash's is just to confirm that each one is unique. _
for the your purposes I would suggest a dictionary(of integer, ulong)
If Not IntList.Contains(HashInt) Then
IntList.Add(HashInt)
End If
Next
UPDATE: modified the code to show that it will produce 100000 unique hash's. IntList.Count = 100000.
For results that end up being less than 16 digits, I padded the end with 0's. This is just convenient. By putting the BitConverter.ToUInt64 result into a string you can insert the 0's anywhere you like.
Upvotes: 1