Using factorials to find combinations - vb.net

So, this is a two part question but based on the same project. I am trying to write a small program that can illustrate how a computer can quickly crack a password, using a brute force attack. It only has three inputs: A check box to denote if it should use integers, a check box to denote if it should use letters, and a textbox to enter the password to be cracked. It then outputs the number of combinations. Here is my code:
dim a,b,c,d,P as double
'Using the following formula:
'P(n,r) = n!/(r!(n-r)!)
'Let's assume we are just using numbers, so n = 10
'r = the count of characters in the textbox.
a = factorial(n)
b = factorial(r)
c = (n - r)
d = factorial(c)
P = a / (b * d)
Output = "With a password of " & r & " characters and " & n & " possible values, the number of combinations are " & P
Me.RichTextBox1.Text = Output & vbCrLf
Function factorial(ByVal n As Integer) As Integer
If n <= 1 Then
Return 1
Else
Return factorial(n - 1) * n
End If
End Function
So, let's assume I'm only looking at the characters 0-9, with the following number of characters in a password, I get:
P(10,1) = 10!/(1! * (10-1)!) = 10
P(10,2) = 10!/(2! * (10-2)!) = 45
P(10,3) = 10!/(3! * (10-3)!) = 120
P(10,4) = 10!/(4! * (10-4)!) = 210
P(10,5) = 10!/(5! * (10-5)!) = 252
P(10,6) = 10!/(6! * (10-6)!) = 210
P(10,7) = 10!/(6! * (10-7)!) = 120
You can see the number of combinations goes down, once it gets past 5. I assume this is right, but wanted to check before I present this. Is this because the total number in the pool remains the same, while the sample increases?
My second question is about how to consider a password to crack that repeats numbers. Again, let's assume that we are just pulling from digits 0-9. If the sample size it two (lets say 15), then there are 45 possible combinations, right? But, what if they put in 55? Are there still 45 combinations? I suppose the computer still needs to iterate over every possible combination, so it would still be considered 45 possibilities?

Related

julia probability password only numbers

new to julia and trying to figure out this probability/proportion code.
The folowing code takes 10^6 passwords and counts what proportion have 1 or less lower case letters.
passLength = 8
numToCheck = 1
possibleChars = ['a':'z';'A':'Z';'0':'9']
#Define a function that counts how characters are lower case
numLowerCaseChars(str) = sum([ islower(char) for char in str])
n = 10^6
passwords = [String(rand(possibleChars ,passLength )) for _ in 1:n]
proportion = sum([ numLowerCaseChars(p) <= numToCheck for p in passwords])/n
I need to alter this code to give me what proportion of passwords consist of solely numbers.
I already know the exact probability is 4.580010609233563e-7 which I've worked out by hand but i cant figure out how to get the same result with this code.
So far I've tried
passLength = 8
numToCheck = 8
possibleChars = ['a':'z';'A':'Z';'0':'9']
#Define a function that counts how many characters are integers
numintegers(str) = sum([ isnumber(char) for char in str])
n = 10^6
passwords = [String(rand(possibleChars ,passLength )) for _ in 1:n]
proportion = sum([numintegers(p) == numToCheck for p in passwords])/n
But this returns 1.0e-6 which is way different. Is this to do with the sample size? I've tried generating more that 10^6 passwords but julia stops working.
Please help me, thanks in advance.

Luhn Algorithm not working

I've encountered a problem with a program I'm writing for school. I need to verify credit card numbers using the Luhn Algorithm, however I'm having some difficulty in getting the logic of the algorithm to work correctly. I believe I know where the problem is, but I'm unable to fix it.
I believe the problem is here:
For i = 0 To cardInput.Text.Length - 2 Step -2
Dim x = (i * 2)
If x > 9 Then
x = x - 9
End If
oddTotal += x
Next
'Sum of undoubled digits
For i = 0 To cardLength - 1 Step -2
evenTotal += i
Next
total = oddTotal + evenTotal
checkSum = total
infoOutput.Items.Add("CheckDigit: " & checkDigit)
infoOutput.Items.Add("CheckSum :" & checkSum)
'Verify that the card is valid by the Mod 10 (Lund algoritm)
If checkSum = checkDigit Or checkSum = 0 Then
valid = True
Else
valid = False
End If
If it's needed, the rest of my project can be seen here
My code doesn't seem to start at the last digit and take every other digit back to the beginning to be doubled. Is the Step -2 operator incorrect here? What am I doing wrong?
There are several problems here. Particularly:
If you want a loop to count backwards, you have to start at the higher index and end at the lower one. So:
For i = cardInput.Text.Length - 2 To 0 Step -2
Then, instead of using i directly, you should use the i-ith digit:
Dim x = Val(cardInput.Text(i))
The same applies to your sum of evens.
If you want to check if the last digit is zero, use the Mod operator:
valid = (checkSum Mod 10 = 0)

Random Number Generation to Memory from a Distribution using VBA

I want to generate random numbers from a selected distribution in VBA (Excel 2007).
I'm currently using the Analysis Toolpak with the following code:
Application.Run "ATPVBAEN.XLAM!Random", "", A, B, C, D, E, F
Where
A = how many variables that are to be randomly generated
B = number of random numbers generated per variable
C = number corresponding to a distribution
1= Uniform
2= Normal
3= Bernoulli
4= Binomial
5= Poisson
6= Patterned
7= Discrete
D = random number seed
E = parameter of distribution (mu, lambda, etc.) depends on choice for C
(F) = additional parameter of distribution (sigma, etc.) depends on choice for C
But I want to have the random numbers be generated into an array, and NOT onto a sheet.
I understand that where the "" is designates where the random numbers should be printed to, but I don't know the syntax for assigning the random numbers to an array, or some other form of memory storage instead of to a sheet.
I've tried following the syntax discussed at this Analysis Toolpak site, but have had no success.
I realize that VBA is not the ideal place to generate random numbers, but I need to do this in VBA. Any help is much appreciated! Thanks!
Using the inbuilt functions is the key. There is a corresponding version for each of these functions but Poisson. In my presented solution I am using an algorithm presented by Knuth to generate a random number from the Poisson Distribution.
For Discrete or Patterned you obviously have to write your custom algorithm.
Regarding the seed you can place a Randomize [seed] before filling your array.
Function RandomNumber(distribution As Integer, Optional param1 = 0, Optional param2 = 0)
Select Case distribution
Case 1 'Uniform
RandomNumber = Rnd()
Case 2 'Normal
RandomNumber = Application.WorksheetFunction.NormInv(Rnd(), param1, param2)
Case 3 'Bernoulli
RandomNumber = IIf(Rnd() > param1, 1, 0)
Case 4 'Binomial
RandomNumber = Application.WorksheetFunction.Binom_Inv(param1, param2, Rnd())
Case 5 'Poisson
RandomNumber = RandomPoisson(param1)
Case 6 'Patterned
RandomNumber = 0
Case 7 'Discrete
RandomNumber = 0
End Select
End Function
Function RandomPoisson(ByVal lambda As Integer) 'Algorithm by Knuth
l = Exp(-lambda)
k = 0
p = 1
Do
k = k + 1
p = p * Rnd()
Loop While p > l
RandomPoisson = k - 1
End Function
Why not use the inbuilt functions?
Uniform = rnd
Normal = WorksheetFunction.NormInv
Bernoulli = iif(rnd()<p,0,1)
Binomial = WorksheetFunction.Binomdist
Poisson = WorksheetFunction.poisson
Patterned = for ... next
Discrete =
-
select case rnd()
case <0.1
'choice 1
case 0.1 to 0.4
'choice 2
case >0.4
'choice 3
end select

How to choose a range for a loop based upon the answers of a previous loop?

I'm sorry the title is so confusingly worded, but it's hard to condense this problem down to a few words.
I'm trying to find the minimum value of a specific equation. At first I'm looping through the equation, which for our purposes here can be something like y = .245x^3-.67x^2+5x+12. I want to design a loop where the "steps" through the loop get smaller and smaller.
For example, the first time it loops through, it uses a step of 1. I will get about 30 values. What I need help on is how do I Use the three smallest values I receive from this first loop?
Here's an example of the values I might get from the first loop: (I should note this isn't supposed to be actual code at all. It's just a brief description of what's happening)
loop from x = 1 to 8 with step 1
results:
x = 1 -> y = 30
x = 2 -> y = 28
x = 3 -> y = 25
x = 4 -> y = 21
x = 5 -> y = 18
x = 6 -> y = 22
x = 7 -> y = 27
x = 8 -> y = 33
I want something that can detect the lowest three values and create a loop. From theses results, the values of x that get the smallest three results for y are x = 4, 5, and 6.
So my "guess" at this point would be x = 5. To get a better "guess" I'd like a loop that now does:
loop from x = 4 to x = 6 with step .5
I could keep this pattern going until I get an absurdly accurate guess for the minimum value of x.
Does anybody know of a way I can do this? I know the values I'm going to get are going to be able to be modeled by a parabola opening up, so this format will definitely work. I was thinking that the values could be put into a column. It wouldn't be hard to make something that returns the smallest value for y in that column, and the corresponding x-value.
If I'm being too vague, just let me know, and I can answer any questions you might have.
nice question. Here's at least a start for what I think you should do for this:
Sub findMin()
Dim lowest As Integer
Dim middle As Integer
Dim highest As Integer
lowest = 999
middle = 999
hightest = 999
Dim i As Integer
i = 1
Do While i < 9
If (retVal(i) < retVal(lowest)) Then
highest = middle
middle = lowest
lowest = i
Else
If (retVal(i) < retVal(middle)) Then
highest = middle
middle = i
Else
If (retVal(i) < retVal(highest)) Then
highest = i
End If
End If
End If
i = i + 1
Loop
End Sub
Function retVal(num As Integer) As Double
retVal = 0.245 * Math.Sqr(num) * num - 0.67 * Math.Sqr(num) + 5 * num + 12
End Function
What I've done here is set three Integers as your three Min values: lowest, middle, and highest. You loop through the values you're plugging into the formula (here, the retVal function) and comparing the return value of retVal (hence the name) to the values of retVal(lowest), retVal(middle), and retVal(highest), replacing them as necessary. I'm just beginning with VBA so what I've done likely isn't very elegant, but it does at least identify the Integers that result in the lowest values of the function. You may have to play around with the values of lowest, middle, and highest a bit to make it work. I know this isn't EXACTLY what you're looking for, but it's something along the lines of what I think you should do.
There is no trivial way to approach this unless the problem domain is narrowed.
The example polynomial given in fact has no minimum, which is readily determined by observing y'>0 (hence, y is always increasing WRT x).
Given the wide interpretation of
[an] equation, which for our purposes here can be something like y =
.245x^3-.67x^2+5x+12
many conditions need to be checked, even assuming the domain is limited to polynomials.
The polynomial order is significant, and the order determines what conditions are necessary to check for how many solutions are possible, or whether any solution is possible at all.
Without taking this complexity into account, an iterative approach could yield an incorrect solution due to underflow error, or an unfortunate choice of iteration steps or bounds.
I'm not trying to be hard here, I think your idea is neat. In practice it is more complicated than you think.

Division in VB.NET

What's the difference between / and \ for division in VB.NET?
My code gives very different answers depending on which I use. I've seen both before, but I never knew the difference.
There are two ways to divide numbers. The fast way and the slow way. A lot of compilers try to trick you into doing it the fast way. C# is one of them, try this:
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine(1 / 2);
Console.ReadLine();
}
}
Output: 0
Are you happy with that outcome? It is technically correct, documented behavior when the left side and the right side of the expression are integers. That does a fast integer division. The IDIV instruction on the processor, instead of the (infamous) FDIV instruction. Also entirely consistent with the way all curly brace languages work. But definitely a major source of "wtf happened" questions at SO. To get the happy outcome you would have to do something like this:
Console.WriteLine(1.0 / 2);
Output: 0.5
The left side is now a double, forcing a floating point division. With the kind of result your calculator shows. Other ways to invoke FDIV is by making the right-side a floating point number or by explicitly casting one of the operands to (double).
VB.NET doesn't work that way, the / operator is always a floating point division, irrespective of the types. Sometimes you really do want an integer division. That's what \ does.
10 / 3 = 3.333
10 \ 3 = 3 (the remainder is ignored)
/ Division
\ Integer Division
10 / 3 = 3.33333333333333, assigned to integer = 3
10 \ 3 = 3, assigned to integer = 3
20 / 3 = 6.66666666666667, assigned to integer = 7
20 \ 3 = 6, assigned to integer = 6
Code for the above:
Dim a, b, c, d As Integer
a = 10 / 3
b = 10 \ 3
c = 20 / 3
d = 20 \ 3
Debug.WriteLine("10 / 3 = " & 10 / 3 & ", assigned to integer = " & a)
Debug.WriteLine("10 \ 3 = " & 10 \ 3 & ", assigned to integer = " & b)
Debug.WriteLine("20 / 3 = " & 20 / 3 & ", assigned to integer = " & c)
Debug.WriteLine("20 \ 3 = " & 20 \ 3 & ", assigned to integer = " & d)