Legals when "randomly" selecting a winner.
So I found this question I was asked this evening interesting. I was told to, very quickly obviously, make a quick tool that generate a random integer. Easy right? But wait! I suppose there is a twist... This is going to be choosing a winner for a grand price. A grand price grand enough that I wish I could win, but for disclosure I can not say much more Lol. So, I was wondering if there are any legals involved when choosing a "random" winner. In all honesty I feel any computational piece of data a computer generates is never really random, so whats second best?
The only way I know of doing such a task is purely basic at best.
vbnet Code:
Public Class Class1
Private rnd As New System.Random(DateTime.Now.Millisecond)
Public Function GenerateRandomInteger(ByVal Minimum As Integer, ByVal Maximum Integer) As Integer
Return rnd.Next(Minimum, Maximum)
End Function
End Class
To get crazy, can we do unique ways of using random.next() to produce a more promising result?
vbnet Code:
Public Class Class1
Private rnd As New System.Random(DateTime.Now.Millisecond)
Public Function GenerateRandomInteger(ByVal Minimum As Integer, ByVal Maximum Integer) As Integer
Dim col As New System.List(Of Integer)
Dim c As Integer = 0
Dim i As Integer = 0
Dim r As Integer = 0
c = rnd.Next(0, 999)
i = rnd.Next(0, 999)
Do
col.Add(rnd.Next(Minimum, Maximum))
While (col.Count < c)
r = col(i)
Return r
End Function
End Class
Idk, this is a rather unusual topic for me to ask, but in business development. I find using random numbers nonexistent.
PS I'm not going to use Random.Org ;)
Re: Legals when "randomly" selecting a winner.
First of all, if you're creating a single Random object then there's no point using the current time as a seed. If you use the constructor with no parameters then it will use the current time anyway, so you may as well just do that. The only reason to use an explicit seed when creating a Random object is that you're creating multiple instances and you need to ensure that a different seed is used in each case.
Secondly, in this case, don't use the Random class. It uses a pseudo-random sequence that is fine for most scenarios but is open to manipulation. In cases like this, you should use the System.Security.Cryptography.RNGCryptoServiceProvider class. It generates data that is sufficiently random to be used in cryptography so it will be fine for what you're doing.
Re: Legals when "randomly" selecting a winner.
Quote:
Originally Posted by
jmcilhinney
It uses a pseudo-random sequence that is fine for most scenarios but is open to manipulation. In cases like this, you should use the System.Security.Cryptography.RNGCryptoServiceProvider class. It generates data that is sufficiently random to be used in cryptography so it will be fine for what you're doing.
Whoa! nail on the head. I can now see why the use of the Random class in this situation is bad. And in all honestly coincided my gut feeling! An interesting solution to. I'll be sure to look into it..on my free time of course, now that this is going to be an all nighter, educating myself further on the Cryptography topic :rolleyes: thanks Lol
Quote:
Originally Posted by
jmcilhinney
First of all, if you're creating a single Random object then there's no point using the current time as a seed.
and a good catch, I actually blindly followed an example after refreshing my memory with a few web searches. Ya know, just to see if anything's changed since VB6 when I last used it!
But again, time and time again. Flaweless responses. Thanks jmcilhinney!
Re: Legals when "randomly" selecting a winner.
Interesting... Here is what I was able to extract from the many examples online. The results seem pretty satisfying to me if I don't say. Feel free to point out any flaw you may notice.
vbnet Code:
Private CryptographicService As New RNGCryptoServiceProvider()
''' <summary>
''' Returns a cryptocraphically generated random number.
''' </summary>
''' <returns>Int32</returns>
''' <remarks>Range has a fixed minimum value of 1.</remarks>
Private Function GetRandomInteger(ByVal Maximum As Int32) As Int32
Dim res(0) As Byte ' Create a byte array to hold the random value.
Do
CryptographicService.GetBytes(res)
Loop While res(0)<=Maximum
Return (System.Convert.ToInt32(res(0)) Mod Maximum) + 1 ' Values are 0 based.
End Function
Re: Legals when "randomly" selecting a winner.
Actually the above post works, but not entirely. I need something with a maximum of 37,000, minimum... Perhaps I'm doing this wrong. But when I use 1000 for a maximum, it never produces a value between 1-1000. The values seem to never be greater than 300ish.
hmmmmm....
Re: Legals when "randomly" selecting a winner.
I would actually inherit the Random class and override the Sample method to use the RNGCryptoServiceProvider class internally, e.g.
Code:
Imports System.Security.Cryptography
Public Class CryptoRandom
Inherits Random
Implements IDisposable
Private ReadOnly rng As New RNGCryptoServiceProvider
Protected Overrides Function Sample() As Double
Dim data(7) As Byte
rng.GetBytes(data)
Dim number = BitConverter.ToDouble(data, 0)
'Normalise the result to the range 0.0 <= N <= 1.0
number = Math.Abs(number / Double.MaxValue)
'Normalise the result to the range 0.0 <= N < 1.0
If number > 0.0 Then
number -= Double.Epsilon
End If
Return number
End Function
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
rng.Dispose()
End If
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
You can now use that CryptoRandom class in exactly the same way as you would the regular Random class. It exposes the exact same interface because it inherits its public methods from the regular Random class. Those methods all call Sample internally and the derived CryptoRandom class will use the implementation above that utilises the RNGCryptoRandomServiceProvider instead of the usual pseudo-random sequence generator.
Re: Legals when "randomly" selecting a winner.
WOW incredible stuff jmcilhinney!
A very neat approach to reuse the Random class. One I didn't even think of doing myself. In all honestly I was trying to stay away from it, but in retrospect I should have done quite the opposite.
This is what I've got so far...
vbnet Code:
Imports System.Security.Cryptography
Public Class CryptoRandom
Inherits Random
Implements IDisposable
Private ReadOnly rng As New RNGCryptoServiceProvider()
Private _Maximum As Double = 0
Sub New(ByVal Maximum As Double)
MyBase.New()
Me._Maximum = Maximum
End Sub
Protected Overrides Function Sample() As Double
Dim data(7) As Byte
Do Until (BitConverter.ToInt64(data, 0) > 0)
rng.GetNonZeroBytes(data)
Loop
Return BitConverter.ToInt64(data, 0) Mod _Maximum
End Function
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' Clean up code.
'rng.Dispose() ' Not accessable? I'm confused.
End If
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Wont spend much more time on this, as my boss man told me not to. But when it's interesting and especially a new topic for me, I simple cannot resist. :)
Re: Legals when "randomly" selecting a winner.
You should do away with that Maximum business. From the outside, this class works just like the Random class. As such, you simply call Next and specify a maximum and it will return an Integer that is less than that maximum but not less than zero, just as you would with the Random class. The only difference is how the random numbers are generated internally.
Re: Legals when "randomly" selecting a winner.
I can't seem to get it to work any other way though. Taking your example, and using .Next(Int32, Int32) to specify a min/max range, I get -2147483648 as a value every single time...
EDIT: Actually I had a bug messing this up going unnoticed, I get 0 every time.
Re: Legals when "randomly" selecting a winner.
That's due to an issue in my code. I've reimplemented that CryptoRandom class and posted it in the CodeBank. You can find it here:
http://www.vbforums.com/showthread.p...m-Random-Class
Re: Legals when "randomly" selecting a winner.
A few years ago I tried some tests to look at the distribution of random numbers. I was actually looking at getting a weighted distribution, but as an early step I confirmed that the distribution of random numbers returned by Random was suitably even. For a single number or two, Random may have some issues, but over a sizeable sample, it does end up being random because the weighting begins to approach even. It takes a large sample, though, or else a true random distribution is not evenly distributed. That has always made me think that a random selection of the results of a large sample of Random results would be quite random....but also too painful to bother with. This approach appears to be a better one.