-
Nov 16th, 2017, 10:27 AM
#1
Thread Starter
New Member
Thought this might help someone (Rnd number sets with a twist)
I don't have an issue with this code, but I thought that someone might could use it or improve on it:
Have you ever needed a randomly generated set of numbers (12345-12347-1234) etc, but to have a little bit above average security yet still be easy to implement into your code, then maybe this will help you out.
This code creates a set of 3 randomly generated numbers plus the year, but the catch is that the first set of numbers adds up to a set number, the second set adds up to a different number and the third set adds up to a different number. then the numbers are split so that they can be verified that they add up to each correct variable.
so for instance the random number set generated is: 65612-1514-9325-2017 | 65612 - the first set adds up to 20, 1514 - the second set adds up to 11, 9325 - the third set adds up to 19 and the final number is the current year (or can be optional)
first we need to create a function to generate a random set of numbers:
Code:
Function grs(ByRef length As Integer) As String
Randomize()
Dim ac As String
ac = "0123456789"
Dim i As Integer
For i = 1 To length
grs = grs & Mid$(ac, Int(Rnd() * Len(ac) + 1), 1)
Next
End Function
then to create the function that will give us the values for each set of numbers, these values can be set in the following code, or you can also have the user set these variables in the registry or settings.
Code:
Function cypt()
Dim a1, a2, a3 As Integer ' Variable for each SET of numbers
Dim va, vb, vc, vd, ve As Integer
Do Until Val(va) + Val(vb) + Val(vc) + Val(vd) + Val(ve) = 20
va = CInt(Int((9 * Rnd()) + 1))
vb = CInt(Int((9 * Rnd()) + 1))
vc = CInt(Int((9 * Rnd()) + 1))
vd = CInt(Int((9 * Rnd()) + 1))
ve = CInt(Int((9 * Rnd()) + 1))
a1 = va & vb & vc & vd & ve
Loop
Dim v1, v2, v3, v4 As Integer
Do Until Val(v1) + Val(v2) + Val(v3) + Val(v4) = 11
v1 = CInt(Int((9 * Rnd()) + 1))
v2 = CInt(Int((9 * Rnd()) + 1))
v3 = CInt(Int((9 * Rnd()) + 1))
v4 = CInt(Int((9 * Rnd()) + 1))
a2 = v1 & v2 & v3 & v4
Loop
Dim v5, v6, v7, v8 As Integer
Do Until Val(v5) + Val(v6) + Val(v7) + Val(v8) = 19
v5 = CInt(Int((9 * Rnd()) + 1))
v6 = CInt(Int((9 * Rnd()) + 1))
v7 = CInt(Int((9 * Rnd()) + 1))
v8 = CInt(Int((9 * Rnd()) + 1))
a3 = v5 & v6 & v7 & v8
Loop
Return a1 & "-" & a2 & "-" & a3 & "-" & Date.Now.Year
End Function
Since we used "-" to separate the number sets in the function above, we can Split these and then verify that they are correct. This code just Displays the result, I have not written any code that will "Verify" if the variables below (c1,c2 or c3) add up to the same as the variables set above (should'nt be that hard).
Code:
Dim s As String = txResult.Text
Dim sp() As String
Dim c1, c2, c3 As Long
sp = s.Split("-")
Label1.Text = sp(0)
For Each nm1 As String In Label1.Text
If Long.TryParse(nm1, Nothing) Then
c1 += nm1
End If
Next
cnt1.Text = c1
Label2.Text = sp(1)
For Each nm2 As String In Label2.Text
If Long.TryParse(nm2, Nothing) Then
c2 += nm2
End If
Next
cnt2.Text = c2
Label3.Text = sp(2)
For Each nm3 As String In Label3.Text
If Long.TryParse(nm3, Nothing) Then
c3 += nm3
End If
Next
cnt3.Text = c3
If someone has improvements, please feel free to post them. Thank you.
-
Nov 16th, 2017, 11:00 AM
#2
Re: Thought this might help someone (Rnd number sets with a twist)
I don't have absolute no idea on what you are doing but I though, since we are on a random spring I would just randomize Colors:
http://www.vbforums.com/showthread.p...51#post5233651
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·
-
Nov 16th, 2017, 11:38 AM
#3
Re: Thought this might help someone (Rnd number sets with a twist)
The code can be improved considerably:
1) Simply put, Randomize and Rnd are legacy methods that are more complicated than they need to be. You are using them in a risky way, too. Randomize seeds the random number generator. If you call it more than once a second, your numbers will be far from random. Since you call Randomize in the grs() method, you'd have to ensure that you don't call the method more than once a second, or you'd get some highly non-random numbers.
2) You can also do a fair amount better than using a string and Mid$. Use an array of integer. String manipulation is always slow, but array access is really fast.
3) Then there's the bit where you are calling Val() on integers. What's that about? Val converts strings to doubles. The best that you are doing with that code is converting integers to doubles slowly. You can just start with doubles, at which point you don't need Val() for anything at all. That would be faster.
4) You are calling CInt(Int()) a bunch of times. That's taking an integer and using a method to convert it to an integer. It already IS an integer, so the best you can hope for is that the compiler recognizes that and drops the CInt(). That likely won't be happening, so you are spending a totally trivial amount of time converting an integer into an integer.
5) Then you have this line:
a1 = va & vb & vc & vd & ve
That is taking a series of integers, implicitly casting them to a string (implicit conversions are slower and slightly risky), concatenating all of the strings together, then implicitly converting the string back to an integer. That last implicit conversion is also slow, and would be much more risky, except that, the way it is written it should always work. Just using explicit conversions would speed this up (despite being longer in appearance):
a1 = CInt(va.ToString & vb.ToString & vc.ToString & vd.ToString & ve.ToString)
6) There's also at least one significant improvement that can be made to the loops, because the last element in each set doesn't have to be part of the loop. For example, in the second loop you are adding v1, v2, v3, and v4 and checking whether they equal 11. In fact, if you randomly generate v1, v2, and v3, you don't need to randomly generate v4, because there can be AT MOST just one value that would satisfy the loop. So, add up v1, v2, and v3. If that is already above 11, then the loop fails. If that sum isn't above 11, then subtract it from 11, and that is the value for v4. No generation of v4 is needed, and the loops will run for considerably fewer iterations. You can do considerably better than that, though. You are looking for four integers from 1 to 9 that add up to 11. If any of the integers is 9, then there can't be three other integers that add up to 11. If any of the integers is 8, then the other three HAVE to be 1. Furthermore, once you generate the first integer, the values for the remaining integers are reduced. This isn't such an issue for the larger targets you have on the other loops, but the same general principle holds: For any value of the first integer, there are values of the second and subsequent integers that would cause the loop to fail, so the range can change depending on the target, and depending on the sum up to that point.
My usual boring signature: Nothing
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|