I am looking for a way to generate a hexadecimal string that equals out to 106 bits, more specifically fifty three 1's and fifty three 0's after each hex char is converted to binary and added together. I'd like to keep it as random as possible considering the parameters of the request. How would I go about keeping an eye on the construction of the string so that it equals out the way I want?
(1010 1000 1100 0000 0101 0111 0111 1001 1111 1000 1001 0011 0100
1011 0001 0100 1100 1110 1001 0110 1111 1000 1010 1010 1001 0011)
You can place 52 ones randomly in a 104 bit number by keeping track of how many ones has been placed already and calculate the probability that the next digit should be one. The first digit always has 1/2 probability (52/104), then the second digit has 51/103 or 52/103 probability depending on what the first digit was, and so on.
Put the bits in a buffer, and when it is full (four bits), that makes a hexadecimal digit that you can add to the string:
Dim rnd As New Random() Dim bin As New StringBuilder() Dim buf As Integer = 0, bufLen As Integer = 0, left As Integer = 52 For i As Integer = 104 To 1 Step -1 buf <<= 1 If rnd.Next(i) < left Then buf += 1 left -= 1 End If bufLen += 1 If bufLen = 4 Then bin.Append("0123456789abcdef"(buf)) bufLen = 0 buf = 0 End If Next Dim b As String = bin.ToString()
To make a 106 bit value, change these lines:
Dim buf As Integer = 0, bufLen As Integer = 0, left As Integer = 53 For i As Integer = 106 To 1 Step -1
The resulting string is still 26 characters, the two extra bits are in the
buf variable. It has a value between
3 that you can use to create the 27th character, however that is done.
To add a 22 bit hash to the string, you can use code like this:
bin.Append("048c"(buf)) Dim b As String = bin.ToString() Dim m As New System.Security.Cryptography.SHA1Managed Dim hash As Byte() = m.ComputeHash(Encoding.UTF8.GetBytes(b)) 'replace first two bits in hash with bits from buf hash(0) = CByte(hash(0) And &H3F Or (buf * 64)) 'append 24 bits from hash b = b.Substring(0, 26) + BitConverter.ToString(hash, 0, 3).Replace("-", String.Empty)