Adam Grolli Adam Grolli - 10 days ago 5
Vb.net Question

How to generate a 26-character hex string that equals to 106 bits and ((53 Ones - 53 Zeros) in binary)

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?

For example:

(a8c05779f8934b14ce96f8aa93) =
(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)

Answer

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 0 and 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)
Comments