Using Excel's comparison operator in VBA? - vba

I'm trying to figure out how I can use the same comparison operator that Excel uses in sorting a mix of alphanumeric values like the following:
0
9
34
51
123abc
15
a
a1b23c
i
z
34ui
10
d
1
12
When sorting this, this is the result:
0
1
9
10
12
15
34
51
123abc
34ui
a
a1b23c
d
i
z
Is it possible to use the comparison operator that Excel uses to get this result? Or is it necessary to create my own function for this?

I just went ahead and created a comparison function with the same return values as StrComp() since it seems there isn't one already.
Function ExcelCompare(ByVal str1 As String, ByVal str2) As Integer
Dim isnum1 As Boolean
Dim isnum2 As Boolean
isnum1 = IsNumeric(str1)
isnum2 = IsNumeric(str2)
ExcelCompare = StrComp(str1, str2)
If isnum1 And Not isnum2 Then
ExcelCompare = -1
ElseIf Not isnum1 And isnum2 Then
ExcelCompare = 1
ElseIf isnum1 And isnum2 Then
Dim num1 As Double
Dim num2 As Double
num1 = CDbl(str1)
num2 = CDbl(str2)
If num1 = num2 Then
ExcelCompare = 0
ElseIf num1 < num2 Then
ExcelCompare = -1
Else
ExcelCompare = 1
End If
End If
End Function

Related

I have problem that says System.Security.Cryptography.CryptographicException: 'Bad Data. ' in vb.net when trying to import RSA parameters

Here's the code I am not sure if there's any hidden error but on runtime when trying to import the rsa parameters it pops up that error
Imports System.Security.Cryptography
Imports System.Security
Imports System.Text
Imports System.IO
Public Class RSA_Test_Form
Public FactorList As New List(Of Integer)
Public FindFactor As Long
Public PString, QString, ModulusString, ExponentString, DString, DPString,
DQString, InverseQString As String
Function ModInverse(ByVal a As Long, ByVal b As Long) As Long
Dim b0 As Long = b
Dim t As Long
Dim q As Long
Dim x0 As Long = 0
Dim x1 As Long = 1
If b = 1 Then Return 1
While a > 1
q = a \ b
t = b
b = a Mod b
a = t
t = x0
x0 = x1 - q * x0
x1 = t
End While
If x1 < 0 Then x1 += b0
Return x1
End Function
Function gcd(ByVal n1 As Long, ByVal n2 As Long) As Long
Dim i As Integer
Dim minimum As Integer
If n1 < n2 Then
minimum = n1
Else
minimum = n2
End If
For i = minimum To 1 Step -1
If n1 Mod i = 0 And n2 Mod i = 0 Then
Return i
End If
Next
Return gcd
End Function
Sub FindFactorFunction()
Dim x As Long
For x = 2 To FindFactor - 1
If FindFactor Mod x = 0 Then
FactorList.Add(x)
End If
Next
End Sub
Private Sub GenerateBTN_Click(sender As Object, e As EventArgs) Handles GenerateBTN.Click
Dim Result As Long = 0
Dim Result2 As Long = 0
Dim Result3 As Long = 0
Dim Random1, Random2 As New Random()
Dim P, Q, Modulus As Long
Dim Exponent, D, DP, DQ As New Nullable(Of Long)
Dim InverseQ As New Nullable(Of ULong)
Dim Modulus1 As Long = 0
Dim LoopCount As Integer = 0
Dim ls, ls2 As New List(Of Long)
Dim PrimeString As String
PrimeString = ""
Using MyNewStreamReader As StreamReader = New StreamReader("AllPrimes.txt")
PrimeString = MyNewStreamReader.ReadLine().ToString
MessageBox.Show(PrimeString)
While PrimeString <> "" And LoopCount <= 1249
ls.Add(Long.Parse(PrimeString))
LoopCount += 1
PrimeString = ""
PrimeString = MyNewStreamReader.ReadLine
End While
End Using
Using MyNewStreamReader2 As StreamReader = New StreamReader("AllPrimes.txt")
PrimeString = ""
PrimeString = MyNewStreamReader2.ReadLine().ToString
LoopCount = 0
MessageBox.Show(PrimeString)
While PrimeString <> ""
If LoopCount >= 1250 And LoopCount <= 2499 Then
ls2.Add(Long.Parse(PrimeString))
End If
LoopCount += 1
PrimeString = ""
PrimeString = MyNewStreamReader2.ReadLine
End While
End Using
Dim rand = Random1.Next(0, ls.Count)
Dim rand2 = Random2.Next(0, ls2.Count)
P = ls(rand)
Q = ls2(rand2)
Result3 = gcd(P, Q)
While Result3 <> 1
rand = Random1.Next(0, ls.Count)
rand2 = Random2.Next(0, ls2.Count)
P = ls(rand)
Q = ls2(rand2)
Result3 = gcd(P, Q)
End While
MessageBox.Show("P= " & P & "Q= " & Q)
Modulus = (P - 1) * (Q - 1)
Modulus1 = Modulus + 1
FindFactor = Modulus1
FindFactorFunction()
Dim Count As Integer = 0
Dim Count2 As Integer = 0
For A As Integer = 0 To FactorList.Count - 1
Result = gcd(FactorList.ElementAt(A), Modulus)
If Result = 1 Then
Count += 1
End If
Next
Dim PositionArray(Count) As Integer
Count = 0
For A As Integer = 0 To FactorList.Count - 1
Result = gcd(FactorList.ElementAt(A), Modulus)
If Result = 1 Then
PositionArray(Count) = FactorList.ElementAt(A)
Count += 1
End If
Next
Dim Number1, Number2 As Long
Dim GetResult As Boolean = False
Count = 0
If PositionArray.Count = 2 Then
Exponent = PositionArray(0)
D = PositionArray(1)
Else
While GetResult = False And Count <> PositionArray.Count
For Count = 0 To PositionArray.Count - 1
For Count2 = Count + 1 To PositionArray.Count - 1
Number1 = PositionArray(Count)
Number2 = PositionArray(Count2)
Result2 = Number1 * Number2 Mod Modulus
If Result2 = 1 Then
GetResult = True
End If
If GetResult = True Then
Exit While
End If
Next
Next
End While
End If
Dim Selection As Integer = MessageBox.Show(Number1 & "=E And D= " & Number2, "Information", MessageBoxButtons.OKCancel, MessageBoxIcon.Information)
If Selection = DialogResult.OK Then
Exponent = Number1
D = Number2
DP = D * P
DQ = D * Q
InverseQ = ModInverse(Q, P)
MessageBox.Show("DP= " & DP)
MessageBox.Show("DQ= " & DQ)
MessageBox.Show("InverseQ= " & InverseQ)
In here when generating RSA numbers, I can not always get the correct numbers so i am using this website to check that i have get the correct RSA numbers and the D and Exponent was not = 0
Exponent=e
Everytime I get Exponent and D, I will always use this website to check P,Q,Exponent and D to make sure it's correct
https://www.cs.drexel.edu/~jpopyack/IntroCS/HW/RSAWorksheet.html
End If
If Exponent.HasValue And D.HasValue Then
PString = P.ToString
QString = Q.ToString
ModulusString = Modulus.ToString
ExponentString = Exponent.ToString
DString = D.ToString
DPString = DP.ToString
DQString = DQ.ToString
InverseQString = InverseQ.ToString
In here all D,P,Q,DP,DQ,Exponent,Modulus,InverseQ value has been calculated and checked
End If
End Sub
Private Sub Number2ByteConverterBTN_Click(sender As Object, e As EventArgs) Handles Number2ByteConverterBTN.Click
If it's possible try check the coding here, perhaps this place was the place that i do it wrongly
I initially thought of using BitCoverter.GetBytes() to convert the long and Ulong datatype value
But in the end, the bitconverter.getbytes() doesn't work for me so i have to first convert all those long and ulong data type values into string then use BYTE.PARSE() to convert the string into byte value
That's how i do it
If let's any experts here confirmed that the coding above worked and all the values are correct then try to check is there any potential error here
Dim PByte, QByte, ModulusByte, ExponentByte, DByte, DPByte, DQByte, InverseQByte As Byte()
ReDim PByte(PString.Count)
ReDim QByte(QString.Count)
ReDim ModulusByte(ModulusString.Count)
ReDim ExponentByte(ExponentString.Count)
ReDim DByte(DString.Count)
ReDim DPByte(DPString.Count)
ReDim DQByte(DQString.Count)
ReDim InverseQByte(InverseQString.Count)
Dim TempPByte, TempQByte, TempModulusByte, TempExponentByte, TempDByte As New Byte
Dim StringBuilder As New StringBuilder
Dim StringBuilder2 As New StringBuilder
Dim StringBuilder3 As New StringBuilder
Dim StringBuilder4 As New StringBuilder
Dim StringBuilder5 As New StringBuilder
Dim StringBuilder6 As New StringBuilder
Dim StringBuilder7 As New StringBuilder
Dim StringBuilder8 As New StringBuilder
For i As Integer = 0 To PString.Length - 1
PByte(i) = Byte.Parse(PString.ElementAt(i))
StringBuilder.Append(PByte(i).ToString)
Next
For i As Integer = 0 To QString.Length - 1
QByte(i) = Byte.Parse(QString.ElementAt(i))
StringBuilder2.Append(QByte(i).ToString)
Next
For i As Integer = 0 To ModulusString.Length - 1
ModulusByte(i) = Byte.Parse(ModulusString.ElementAt(i))
StringBuilder3.Append(ModulusByte(i).ToString)
Next
For i As Integer = 0 To ExponentString.Length - 1
ExponentByte(i) = Byte.Parse(ExponentString.ElementAt(i))
StringBuilder4.Append(ExponentByte(i).ToString)
Next
For i As Integer = 0 To DString.Length - 1
DByte(i) = Byte.Parse(DString.ElementAt(i))
StringBuilder5.Append(DByte(i).ToString)
Next
For i As Integer = 0 To DPString.Length - 1
DPByte(i) = Byte.Parse(DPString.ElementAt(i))
StringBuilder6.Append(DPByte(i).ToString)
Next
For i As Integer = 0 To DQString.Length - 1
DQByte(i) = Byte.Parse(DQString.ElementAt(i))
StringBuilder7.Append(DQByte(i).ToString)
Next
For i As Integer = 0 To InverseQString.Length - 1
InverseQByte(i) = Byte.Parse(InverseQString.ElementAt(i))
StringBuilder8.Append(InverseQByte(i).ToString)
Next
Dim MyRSAParams As New RSAParameters
MyRSAParams.P = PByte
MyRSAParams.Q = QByte
MyRSAParams.Exponent = ExponentByte
MyRSAParams.Modulus = ModulusByte
MyRSAParams.D = DByte
MyRSAParams.DP = DPByte
MyRSAParams.DQ = DQByte
MyRSAParams.InverseQ = InverseQByte
Dim MyRSA As RSA
MyRSA = RSA.Create()
MyRSA.ImportParameters(MyRSAParams)
End Sub
Private Sub RSA_Test_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim temp, temp2 As Integer
temp = gcd(1, 2)
temp2 = gcd(2, 3)
FindFactor = 0
End Sub
End Class
What I am trying to do in the generate button was to create the suitable parameters for RSA.
The parameters I was actually able to generate them but in either ULong or Long data type.
When i first convert them into array of Bytes I have considered to use BitConverter but it doesn't work at least in my case.
The only way i am only able to make them into array of Bytes was by making the ULong or Long data type variable into string.
Then convert those string into Byte then put them into ByteArray
I hope it was correct but it is out of my reach for now.
Any ideas on how can i make the parameter data to be accepted as rsa parameter?

Visual basics help-Variables in for loop

I'm trying to get the integers of "num3"(input from the user) and squaring each character and eventually see if its a "happy number"=1 or a "unhappy number" includes 4
For example, 19 is happy number 1^2+9^2=82 , 8^2+2^2=68,6^2+8^2=100, 1^2+0+0=1
Sub Main()
Dim number, num2, total As Integer
Dim num3 As String
Console.Write("pick a number:")
number = Console.ReadLine()
num2 = 0
num3 = Convert.ToString(number)
Do Until total = 1 Or num2 = 4
For Each num3 In num3.Substring(0, num3.Length)
For counter = 1 To num3.Length And num3 = num3.Substring(0, num3.Length)
num2 = num3 ^ 2
total = total + num2
Console.WriteLine(total)
Next
num3 = total
Next
Loop
Console.ReadLine()
If total = 1 Then
Console.WriteLine("happy number")
ElseIf num2 = 4 Then
Console.WriteLine(number & "is a unhappy number")
Console.ReadLine()
End If
End Sub
End Module
however i'm stuck whether "num3" replace itself from the for loop
Here, I believe this should work:
Dim InputNum As Integer = 45 'Your input number
Dim TempNum As Integer = InputNum 'Here we hold number temporarily during steps 19>82....
Do
Dim SumTotal As Double = 0 'sum of numbers squares
For Each number As Char In TempNum.ToString
SumTotal += Integer.Parse(number) ^ 2
Next
TempNum = CInt(SumTotal)
Debug.Print(TempNum.ToString)
'If result is 4 it will loop forever
If SumTotal = 4 Then
Console.WriteLine(InputNum & " is an unhappy number")
Exit Do
ElseIf SumTotal = 1 Then
Console.WriteLine(InputNum & " is a happy number")
Exit Do
End If
Loop

Converting fractions into integers and dividing them in an if statement only returning zero

Purpose: Take two fractions inputted on another platform and by user and evaluate them with IsNothing. If they aren't integers or strings that can be converted, run through Frac2Num (attached, I know this works, not the focus. Code created by Jeff Arms of Arecon Data).
It then checks to see if value A2 is greater than one. If so, then performs the math function (A2/2) - (A1/2) and then returns that value. Else, it returns 0.
So far I have only been able to return 0, so something with how it is reading the values or how its returning the value after the equation is messing it up, I think.
Main function:
Public Function MyFunction(ByVal A1 As String, ByVal A2 As String) As Integer
MyFunction= 0
Try
Dim B1 As Double
Dim B2 As Double
If IsNothing(A1) Then Return 0 'If the user provides no values, return 0.
If IsNothing(A2) Then Return 0 'If the user provides no values, return 0.
If IsNumeric(A1) = True Then
B1 = CDbl(A1)
Else
B1 = Frac2Num(A1)
End If 'If the value is an integer or convertible string, convert value to double. If not, run through Frac2Num function.
If IsNumeric(A2) = True Then
B2 = CDbl(A2)
Else
B2 = Frac2Num(A2)
End If
If A2 > 1 Then
MyFunction= (A2 / 2) - (A1 / 2)
Return MyFunction
Else MyFunction= 0
End If 'If A2 is greater than one, then MyFunction = value created by equation.
Catch ex As Exception
End Try
Frac2Num function:
Function Frac2Num(ByVal X As String) As Double
Dim P As Integer, N As Double, Num As Double, Den As Double
X = Trim$(X)
P = InStr(X, "/")
If P = 0 Then
N = Val(X)
Else
Den = Val(Mid$(X, P + 1))
If Den = 0 Then Error 11 ' Divide by zero
X = Trim$(Left$(X, P - 1))
P = InStr(X, " ")
If P = 0 Then
Num = Val(X)
Else
Num = Val(Mid$(X, P + 1))
N = Val(Left$(X, P - 1))
End If
End If
If Den <> 0 Then
N = N + Num / Den
End If
Frac2Num = N
End Function
Returning:
Sub Main()
Dim result As Integer
result = MyFunction("8 1/2", "8 5/8") 'Function called with example values.
Console.WriteLine(result)
Console.ReadLine()
End Sub
First of all, in the end of your code you are trying to convert a fraction string directly to a number, witch is causing your code to generate an exception and go to the Catch block
change it to
'You are using A1 and A2, change it to B1 and B#
If B2 > 1 Then
MyFunction = (B2 * 1.0 / 2) - (B1 * 1.0 / 2)
Return MyFunction
Else : MyFunction = 0
End If
also, you are returning an integer and assigning the result to an integer. Even if the result was computed properly in your example case it will not be evaluated correctly. Changing it to Double should solve it.
Public Function MyFunction(ByVal A1 As String, ByVal A2 As String) As Double
and
Dim result As Double
result = MyFunction("8 1/2", "8 5/8")

Automatic Calculation with given numbers

I would like to make CPU to calculate declared result from the given numbers that are also declared.
So far:
Dim ArrayOperators() As String = {"+", "-", "*", "/", "(", ")"}
Dim GlavniBroj As Integer = GBRnb() 'Number between 1 and 999 that CPU needs to get from the numbers given below:
Dim OsnovniBrojevi() As Integer = {OBRnb(), OBRnb(), OBRnb(), OBRnb()} '4 numbers from 1 to 9
Dim SrednjiBroj As Integer = SBRnb() '1 number, 10, 15 or 20 chosen randomly
Dim KrajnjiBroj As Integer = KBRnb() '25, 50, 75 or 100 are chosen randomly
Private Function GBRnb()
Randomize()
Dim value As Integer = CInt(Int((999 * Rnd()) + 1))
Return value
End Function
Private Function OBRnb()
Dim value As Integer = CInt(Int((9 * Rnd()) + 1))
Return value
End Function
Private Function SBRnb()
Dim value As Integer = CInt(Int((3 * Rnd()) + 1))
If value = 1 Then
Return 10
ElseIf value = 2 Then
Return 15
ElseIf value = 3 Then
Return 20
End If
Return 0
End Function
Private Function KBRnb()
Dim value As Integer = CInt(Int((4 * Rnd()) + 1))
If value = 1 Then
Return 25
ElseIf value = 2 Then
Return 50
ElseIf value = 3 Then
Return 75
ElseIf value = 4 Then
Return 100
End If
Return 0
End Function
Is there any way to make a program to calculate GlavniBroj(that is GBRnb declared) with the help of the other numbers (also without repeating), and with help of the given operators? Result should be displayed in the textbox, in a form of the whole procedure of how computer got that calculation with that numbers and operators. I tried to make it work by coding operations one by one, but that's a lot of writing... I'm not looking exactly for the code answer, but mainly for the coding algorithm. Any idea? Thanks! :)

do not understand if else block behaviour

I have the following code:
Sub Main()
Dim a As Integer = 8 * 60
Dim b As Integer
Dim c As Integer
If a < (6 * 60) Then
b = 0 And c = 0
ElseIf a >= 6 * 60 And a < 9 * 60 Then
b = 30 And c = 1
Else
b = 45 And
c = 1
End If
MsgBox(b)
End Sub
Thinks i dont understand and where i need someones help:
"c=0" and "c=1" are underlined with the error: Strict on doesnt allow implicit convertation from boolean to integer. WHY? I declared c as integer!
Variable "b" and "c" are always "0" even though in the case above they should be b=30 and c = 1.
can anyone please explain me this behaviour.
You are using the And keyword where it is not allowed. And is a logical operator (along with Or, AndAlso, OrElse.)
The following should work.
Sub Main()
Dim a As Integer = 8 * 60
Dim b As Integer
Dim c As Integer
If a < (6 * 60) Then
b = 0
c = 0
ElseIf a >= 6 * 60 And a < 9 * 60 Then
b = 30
c = 1
Else
b = 45
c = 1
End If
MsgBox(b)
End Sub