Mersenne Twister
The Mersenne Twister is a pseudorandom number generator (PRNG). It is by far the most widely used general-purpose PRNG. Its name derives from the fact that its period length is chosen to be a Mersenne prime.
Private Const N As UInteger = 624
Private Const M As UInteger = 397
Private Const K As UInteger = &H9908B0DFUI
Private Shared state As UInteger() = New UInteger(N) {}
Private Shared nextRand As UInteger
Private Shared left As Integer = -1
Private Shared Function HighestBit(u As UInteger) As UInteger
Return ((u) And &H80000000UI)
End Function
Private Shared Function LowestBit(u As UInteger) As UInteger
Return ((u) And &H1UI)
End Function
Private Shared Function LowestBits(u As UInteger) As UInteger
Return ((u) And &H7FFFFFFFUI)
End Function
Private Shared Function MixBits(u As UInteger, v As UInteger) As UInteger
Return (HighestBit(u) Or LowestBits(v))
End Function
Private Shared Function Increment(ByRef u As UInteger) As UInteger
Dim temp = u
u += 1
Return temp
End Function
Private Shared Function Increment(ByRef u As Integer) As Integer
Dim temp = u
u += 1
Return temp
End Function
Private Shared Function Decrement(ByRef u As Integer) As Integer
u -= 1
Return u
End Function
Public Shared Sub Seed(_seed As UInteger)
Dim x As UInteger = (_seed Or 1UI) And &HFFFFFFFFUI
Dim s As UInteger() = state
Dim j As Integer
Dim i As Integer = 0
left = 0
s(Increment(i)) = x
j = CInt(N)
While Convert.ToBoolean(Decrement(j))
x = (CLng(x) * 69069UI) And UInteger.MaxValue
s(Increment(i)) = (x) And &HFFFFFFFFUI
End While
End Sub
Private Shared Function Reload() As UInteger
Dim p0 As UInteger = 0
Dim p2 As UInteger = 2
Dim pM As UInteger = M
Dim s0 As UInteger
Dim s1 As UInteger
Dim j As Integer
If left < -1 Then
Seed(4357UI)
End If
left = CInt(N - 1)
nextRand = state(1)
s0 = state(0)
s1 = state(1)
j = CInt(N - M + 1)
While Convert.ToBoolean(Decrement(j))
state(Increment(p0)) = state(Increment(pM)) Xor (MixBits(s0, s1) >> 1) Xor (If(Convert.ToBoolean(LowestBit(s1)), K, 0UI))
s0 = s1
s1 = state(Increment(p2))
End While
pM = 0
j = CInt(M)
While Convert.ToBoolean(Decrement(j))
state(Increment(p0)) = state(Increment(pM)) Xor (MixBits(s0, s1) >> 1) Xor (If(Convert.ToBoolean(LowestBit(s1)), K, 0UI))
s0 = s1
s1 = state(Increment(p2))
End While
s1 = state(0)
state(p0) = state(pM) Xor (MixBits(s0, s1) >> 1) Xor (If(Convert.ToBoolean(LowestBit(s1)), K, 0UI))
s1 = s1 Xor (s1 >> 11)
s1 = s1 Xor (s1 << 7) And &H9D2C5680UI
s1 = s1 Xor (s1 << 15) And &HEFC60000UI
Return (s1 Xor (s1 >> 18))
End Function
Public Shared Function Random() As UInteger
Dim y As UInteger
If Decrement(left) < 0 Then
Return Reload()
End If
y = Increment(nextRand)
y = y Xor (y >> 11)
y = y Xor (y << 7) And &H9D2C5680UI
y = y Xor (y << 15) And &HEFC60000UI
Return (y Xor (y >> 18))
End Function
Example
Seed(15858)
Dim rand = Random()
Output
3748065792