Sawyer was talking with a co-worker about how their unique session IDs got created. The concern was that they were only five characters long, which meant there could easily be collisions.

They started by looking at the random number generation function.

    Public Function RandomNumberGenerator(ByVal min As Integer, ByVal max As Integer, Optional ByVal numDecimals As Integer = 0) As String
        '*** the generates a number as a string
        Dim strNum As New StringBuilder
        Dim rnd As New System.Random
        Dim i, x, n As Integer

        Try
            i = rnd.Next(min, max)

            If numDecimals > 0 Then
                Try
                    strNum.Append("9", numDecimals)
                    n = CType(strNum.ToString, Int32)
                    x = rnd.Next(0, n)
                Catch ex As Exception
                    x = 1
                End Try
            End If

            strNum.Remove(0, strNum.Length)
            strNum.Append(i.ToString())

            If numDecimals > 0 Then
                strNum.Append(".")
                If numDecimals > 99 Then
                    numDecimals = 99
                End If
                strNum.Append(x.ToString("D" & numDecimals.ToString()))
            End If

            Return strNum.ToString
        Catch
            Return "1.00"
        End Try
    End Function

You always know it's going to be bad when you see the random number generator returns a string.

If numDecimals is zero, the code is bad, but vaguely sane. Generate a random number using the built in functions, then return it- as a string.

It's the use of numDecimals which makes this weird. We start by appending "9"s to our string builder, converting it to an integer, and then generating a random number from zero to whatever number of nines we're using. This is the code of someone who hates and fears logarithms.

Then we clear out our string builder because we're starting over with the actual number. Then we append a ".", then we append our number, formatted with our number of decimals string, which we force to be no larger than 99. And this is where we get the special kind of weird.

When we're generating our random decimal number, we do this: strNum.Append("9", numDecimals). This is going to put numDecimals 9s on the string. E.g., if numDecimals is 9, this would set strNum to be 999999999. Thus, when we generate a random number, we generate one between 0 and 99999999.

But, when we append that formatted value to the string, we do this:

If numDecimals > 99 Then
    numDecimals = 99
End If
strNum.Append(x.ToString("D" & numDecimals.ToString()))

Here, we're treating numDecimals as a format string. We're only ever going to output two digits.

The only good news is that while this random function was used everywhere, it wasn't used to generate their random IDs. The bad news, this is how their random IDs.

    Public Function RandomQueryStringGenerator() As String
        '*** the generates an alpha-numeric string 5 digits long such as aa7bb
        Dim strPwd As New StringBuilder
        Dim rnd As New System.Random
        Dim i As Integer

        Try
            For x As Integer = 1 To 5
                Select Case x
                    Case 1, 2, 4, 5, 8, 9
                        i = rnd.Next(97, 122)
                        If i Mod 2 = 0 Then
                            strPwd.Append(Chr(i).ToString().ToUpper())
                        Else
                            strPwd.Append(Chr(i).ToString())
                        End If
                    Case Else
                        i = rnd.Next(0, 9)
                        strPwd.Append(i.ToString())
                End Select
            Next x
            Return strPwd.ToString()
        Catch
            Return String.Empty
        End Try
    End Function
[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!