UID Validation - Verhoeff's Algorithm - vba

I am using MS Access & SQL.
I wish to validate 0.1 Mn UID Numbers (Aadhar Cards) for their authenticity.
The UID is based on Verhoeff's Algorithm.
I did find some queries online. They pertained to C++/Java.
Is there a query which validates 0.1 Mn in MS Access for SQL?

As mentioned by Gord Thempson in the comments, you can find the VBA (and many more implementation on the Wikipedia page
For the sake of completeness,
''' <summary>
''' For more information cf. http://en.wikipedia.org/wiki/Verhoeff_algorithm
''' Dihedral Group: http://mathworld.wolfram.com/DihedralGroup.html
''' You can use this code in Excel, Access, etc...
''' </summary>
''' <remarks></remarks>
'The multiplication table
Dim d(0 To 9) As Variant
'The permutation table
Dim p(0 To 8) As Variant
'The inverse table
Dim inv(0 To 9) As Integer
Private Sub initVerhoeffConsts()
If IsArray(d(0)) Then Exit Sub 'Shortcut if already initiated
d(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
d(1) = Array(1, 2, 3, 4, 0, 6, 7, 8, 9, 5)
d(2) = Array(2, 3, 4, 0, 1, 7, 8, 9, 5, 6)
d(3) = Array(3, 4, 0, 1, 2, 8, 9, 5, 6, 7)
d(4) = Array(4, 0, 1, 2, 3, 9, 5, 6, 7, 8)
d(5) = Array(5, 9, 8, 7, 6, 0, 4, 3, 2, 1)
d(6) = Array(6, 5, 9, 8, 7, 1, 0, 4, 3, 2)
d(7) = Array(7, 6, 5, 9, 8, 2, 1, 0, 4, 3)
d(8) = Array(8, 7, 6, 5, 9, 3, 2, 1, 0, 4)
d(9) = Array(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
p(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
p(1) = Array(1, 5, 7, 6, 2, 8, 3, 0, 9, 4)
p(2) = Array(5, 8, 0, 3, 7, 9, 6, 1, 4, 2)
p(3) = Array(8, 9, 1, 6, 0, 4, 3, 5, 2, 7)
p(4) = Array(9, 4, 5, 3, 1, 2, 6, 8, 7, 0)
p(5) = Array(4, 2, 8, 6, 5, 7, 3, 9, 0, 1)
p(6) = Array(2, 7, 9, 3, 8, 0, 6, 4, 1, 5)
p(7) = Array(7, 0, 4, 6, 9, 1, 3, 2, 5, 8)
inv(0) = 0: inv(1) = 4: inv(2) = 3: inv(3) = 2: inv(4) = 1
inv(5) = 5: inv(6) = 6: inv(7) = 7: inv(8) = 8: inv(9) = 9
End Sub
''' <summary>
''' Validates that an entered number is Verhoeff compliant.
''' </summary>
''' <param name="num"></param>
''' <returns>True if Verhoeff compliant, otherwise false</returns>
''' <remarks>Make sure the check digit is the last one!</remarks>
Public Function validateVerhoeff(ByVal num As String) As Boolean
initVerhoeffConsts
Dim c As Integer
Dim i As Integer
c = 0
Dim myArray() As Integer
myArray = StringToReversedIntArray(num)
For i = 0 To UBound(myArray)
c = d(c)(p((i Mod 8))(myArray(i))) 'Version corrected by WHG gives error
Next i
validateVerhoeff = (c = 0)
End Function
''' <summary>
''' For a given number generates a Verhoeff digit
''' </summary>
''' <param name="num"></param>
''' <returns>Verhoeff check digit as Integer</returns>
''' <remarks>Append this check digit to num</remarks>
Public Function generateVerhoeff(ByVal num As String) As Integer
initVerhoeffConsts
Dim c As Integer
Dim i As Integer
c = 0
Dim myArray() As Integer
myArray = StringToReversedIntArray(num)
For i = 0 To UBound(myArray)
c = d(c)(p((i + 1) Mod 8)(myArray(i))) 'Version corrected by WHG gives error in compilation
Next i
generateVerhoeff = inv(c) 'str(inv(c))
End Function
''' <summary>
''' Converts a string to a reversed integer array.
''' </summary>
''' <param name="str"></param>
''' <returns>Reversed integer array</returns>
''' <remarks></remarks>
Private Function StringToReversedIntArray(ByVal str As String) As Integer()
Dim lg As Integer
lg = Len(str)
Dim myArray() As Integer
ReDim myArray(0 To lg - 1)
Dim i As Integer
For i = 0 To lg - 1
myArray(i) = AscW(Mid$(str, lg - i, 1)) - AscW("0")
Next
StringToReversedIntArray = myArray
End Function
''' In Excel don't copy this sub _AssertsVerhoeff()as get a compilation error. 4/21/2013
Public Sub _AssertsVerhoeff()
Debug.Print "Start Verhoeff's Asserts"
Debug.Assert generateVerhoeff("75872") = 2
Debug.Assert validateVerhoeff("758722") = True
Debug.Assert generateVerhoeff("12345") = 1
Debug.Assert validateVerhoeff("123451") = True
Debug.Assert generateVerhoeff("142857") = 0
Debug.Assert validateVerhoeff("1428570") = True
Debug.Assert generateVerhoeff("123456789012") = 0
Debug.Assert validateVerhoeff("1234567890120") = True
Debug.Assert generateVerhoeff("8473643095483728456789") = 2
Debug.Assert validateVerhoeff("84736430954837284567892") = True
Debug.Assert generateVerhoeff("12345") = 1
Debug.Assert validateVerhoeff("123451") = True
Debug.Assert validateVerhoeff("124351") = False
Debug.Assert validateVerhoeff("122451") = False
Debug.Assert validateVerhoeff("128451") = False
Debug.Assert validateVerhoeff("214315") = False
Debug.Print "End Verhoeff's Asserts"
End Sub

Related

Collection of list of integer changing number to access the different variable names

Public p1 = New List(Of Integer)({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
Public p2 = New List(Of Integer)({5, 4, 6, 7, 3, 8, 9, 10, 2, 11})
Public p3 = New List(Of Integer)({11, 8, 10, 9, 7, 12, 6, 13, 14, 15})
I want to display the list p depending on how much is A. if a is 1 then it will be p1, if a is 2 then it will be p2. how can i access the list using this loop without having to manually write the code so many times.
For a As Integer = 1 To 20
If strDigit(str) = a Then
If a = 1 Then
Dim astr As Integer = 0
For Each num In p1
astr = Val(astr) + 1
If num + 1 >= 1 AndAlso num + 1 <= 1000 Then
If pos < 5 Then
Else
End If
End If
Next
ElseIf a = 2 Then
For Each num In p2
Dim astr As Integer = 0
If num + 1 >= 1 AndAlso num + 1 <= 1000 Then
If pos < 5 Then
Else
End If
End If
Next
ElseIf a = 3 Then
For Each num In p3
Dim astr As Integer = 0
astr = Val(astr) + 1
If num + 1 >= 1 AndAlso num + 1 <= 1000 Then
If pos < 5 Then
Else
End If
Next
This should normally be the case, but it doesn't work that way.
For a As Integer = 1 To 20
If strDigit(str) = a Then
If a = 1 Then ' remove line
Dim astr As Integer = 0
For Each num In p(a) ' here
astr = Val(astr) + 1
If num + 1 >= 1 AndAlso num + 1 <= 1000 Then
If pos < 5 Then
Else
End If
End If
Next
End If
Try this one with sorted list
Dim slist As New SortedList(Of Integer, List(Of Integer))
Dim p1 = New List(Of Integer)({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
slist.Add(1, p1)
Dim p2 = New List(Of Integer)({5, 4, 6, 7, 3, 8, 9, 10, 2, 11})
slist.Add(2, p2)
Dim p3 = New List(Of Integer)({11, 8, 10, 9, 7, 12, 6, 13, 14, 15})
slist.Add(3, p3)
Dim p4 = New List(Of Integer)({9, 16, 2, 43, 12, 11, 21, 22, 23})
slist.Add(4, p4)
Dim tmpList As List(Of Integer)
For Each a In slist.Keys
If slist.ContainsKey(a) = True Then
tmpList = slist.Item(a)
For Each num In tmpList
astr = Val(astr) + 1
If num + 1 >= 1 AndAlso num + 1 <= 1000 Then
If pos < 5 Then
Else
End If
End If
Next
End If
Next
LINQ is a great way to make code that would normally involve a loop more succinct.
Dim lists = {p1, p2, p3}
Dim list = lists.First(Function(l) l.Contains(A))
If more than one list contains the specified number, that code will return the first one in which it is found, so that would depend on the order you search them.

Extract specific number from a textboxes

How can I extract from this Textbox, for example what is in parentheses (9,2,8)
Textbox1.Text =
1, 3, 5, 6, 7, 11, 12, 13, 14, 20 (9)
5, 6, 10, 11, 12, 15, 17, 18, 19, 20 (2)
2, 3, 5, 6, 11, 13, 17, 18, 19, 20 (8)
And display in another textbox, Textbox2.Text = 9,2,8
There is another way of doing it.
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Dim s1 = "1, 3, 5, 6, 7, 11, 12, 13, 14, 20 (9)
5, 6, 10, 11, 12, 15, 17, 18, 19, 20 (2)
2, 3, 5, 6, 11, 13, 17, 18, 19, 20 (8)"
Dim re = New Regex("\(([^)]*)\)")
Dim things = re.Matches(s1)
For Each m As Match In things
Console.WriteLine(m.Groups(1).Value)
Next
Console.ReadLine()
End Sub
End Module
Outputs:
9
2
8
For this regular expression, I think a railroad diagram helps to explain what it does:
From https://regexper.com/#%5C%28%28%5B%5E%29%5D*%29%5C%29
You can achieve your desired result using a simple While loop
<TestMethod()>
Public Sub ExtractNumbersInParentheses()
Dim inputString As String = "1, 3, 5, 6, 7, 11, 12, 13, 14, 20 (9)
5, 6, 10, 11, 12, 15, 17, 18, 19, 20 (2)
2, 3, 5, 6, 11, 13, 17, 18, 19, 20 (8)"
Dim finalResult As String = String.Empty
Dim startingPosition As Integer = inputString.IndexOf("(", 0)
While (startingPosition > 0)
If (finalResult.Length > 0) Then finalResult += ", "
Dim extractedText = inputString.Substring(startingPosition + 1, 1)
finalResult += extractedText
startingPosition = inputString.IndexOf("(", startingPosition + 1)
End While
Debug.Print(finalResult)
End Sub
The key part is the .IndexOf function and each time you query the inputString you move the starting position to be beyond the current position otherwhise you will see the same parenthesis
After I ran this test, the output was:
9, 2, 8

Securely store password in a VBA project

I built a file used by various people in one of my company service.
Each sheet is protected by a password and all users entries are handled with a VBA user form. All sheets are protected by the same password and my code protect/unprotect sheet when users modify data.
The problem is I'm storing the password in clear text in the VBA project so as to call the ActiveSheet.Protect password method. The VBA project is also protected by this password.
Is there a secure way to store that password in the VBA project ?
Anyone who knows how to search a bit would find a code to crack that VBA project password and be able to read it.
EDIT :
I have thought of computing a new password each time the file is open by adding some randomness in it. This way one could read the code without knowing the password. Adding a msgbox could reveal it but only until the file is reopenend. The problem is I cannot manually unprotect/protect sheet with that method as I won't be aware of the password.
Summarising the useful info from comments:
if your code has access to the password (even directly or through obfuscation) anybody having access to the code have access to the password too
password protection of Excel VBA is very weak, it's a trivial job to crack it
Conclusion : there is no way securely storing password in Excel VBA
This should do the trick. The password is smp2smp2, which you will get when running GetPassword, but that actual value is not stored in the project. It is stored using the code 30555112012321187051111661144119, which will be converted to the actual password (human readable) by using CreatePasswordFromCode. By the way, I have no idea how to easily get the code that belongs to a certain password. And in this way, it is always 8 characters long, no room for changes unless you adjust the code. I have found this somewhere in an old project of somebody else, no source mentioned unfortunately.
Option Explicit
Function GetPassword() As String
'the password is stored as codes, so the real password is not stored in this project
GetPassword = CreatePasswordFromCode("30555112012321187051111661144119")
End Function
Function CreatePasswordFromCode(ByVal pstrPasswordCode As String) As String
Dim intChar As Integer
Dim intCode As Integer
Dim arrintShifts(0 To 7) As Integer
Dim arrlngCharCode(0 To 7) As Long
Dim strMessage As String
intChar = 0
intCode = 0
For intCode = 0 To 7
'store -8 to -1 into 0-7
arrintShifts(intCode) = intCode - 8
Next intCode
'the code is stored by using the number of the letter of the password in the 4th character.
'the real code of the character is directly behind that.
'so the code 30555112012321187051111661144119
'has on position 3, 055, 5, 112, 0, 123, 2, 118, 7, 051, 1, 116, 6, 114 and 4, 119
'so sorted this is 0, 123, 1, 116, 2, 118, 3, 055, 4, 119, 5, 112, 6, 114, 7, 051
'then there is also the part where those charcode are shifted by adding -8 to -1 to them.
'leading to the real charactercodes:
'0, 123-8, 1, 116-7, 2, 118-6, 3, 055-5, 4, 119-4, 5, 112-3, 6, 114-2, 7, 051-1
'0, 115, 1, 109, 2, 112, 3, 050, 4, 115, 5, 109, 6, 112, 7, 050
For intChar = 0 To 7
If Mid(pstrPasswordCode, 1, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 2, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 5, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 6, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 9, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 10, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 13, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 14, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 17, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 18, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 21, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 22, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 25, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 26, 3) + arrintShifts(intChar))
ElseIf Mid(pstrPasswordCode, 29, 1) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, 30, 3) + arrintShifts(intChar))
End If
Next intChar
'by getting the charcodes of these values, you create the password
CreatePasswordFromCode = Chr(arrlngCharCode(0)) & Chr(arrlngCharCode(1)) & Chr(arrlngCharCode(2)) & Chr(arrlngCharCode(3)) & Chr(arrlngCharCode(4)) & Chr(arrlngCharCode(5)) & Chr(arrlngCharCode(6)) & Chr(arrlngCharCode(7))
End Function
Modified the code for use with up to 99 characters. Added Password generator.
But still: this all is just an obfuscation of the real password.
Function CreatePasswordFromCode(ByVal pstrPasswordCode As String) As String
' Original Code https://stackoverflow.com/questions/47990187/securely-store-password-in-a-vba-project?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
' Modified to extend password length
' Modifications free to use
Dim codeLen As Integer
Dim intChar As Integer
Dim intCode As Integer
Dim arrintShifts() As Integer
Dim arrlngCharCode() As Long
Dim icp As Integer
' Initialise Arrays
icp = IIf(Right(pstrPasswordCode, 1) Mod 2 = 0, 5, 4)
pstrPasswordCode = Left(pstrPasswordCode, Len(pstrPasswordCode) - IIf(Right(pstrPasswordCode, 1) Mod 2 = 0, 1, 1))
codeLen = Len(pstrPasswordCode) / icp - 1 ' Array Index starts with 0
ReDim arrintShifts(codeLen)
ReDim arrlngCharCode(codeLen)
intChar = 0
intCode = 0
For intCode = 0 To codeLen
'store -8 to -1 into 0-7
arrintShifts(intCode) = intCode - (codeLen + 1)
Next intCode
'the code is stored by using the number of the letter of the password in the 4th character.
'the real code of the character is directly behind that.
'so the code 30555112012321187051111661144119
'has on position 3, 055, 5, 112, 0, 123, 2, 118, 7, 051, 1, 116, 6, 114 and 4, 119
'so sorted this is 0, 123, 1, 116, 2, 118, 3, 055, 4, 119, 5, 112, 6, 114, 7, 051
'then there is also the part where those charcode are shifted by adding -8 to -1 to them.
'leading to the real charactercodes:
'0, 123-8, 1, 116-7, 2, 118-6, 3, 055-5, 4, 119-4, 5, 112-3, 6, 114-2, 7, 051-1
'0, 115, 1, 109, 2, 112, 3, 050, 4, 115, 5, 109, 6, 112, 7, 050
For intChar = 0 To codeLen
For intCode = 0 To codeLen
If CInt(Mid(pstrPasswordCode, intCode * icp + 1, icp - 3)) = intChar Then
arrlngCharCode(intChar) = (Mid(pstrPasswordCode, (intCode + 1) * icp - 2, 3) + arrintShifts(intChar))
Exit For
End If
Next intCode
Next intChar
'by getting the charcodes of these values, you create the password
CreatePasswordFromCode = ""
For intChar = 0 To codeLen
CreatePasswordFromCode = CreatePasswordFromCode & Chr(arrlngCharCode(intChar))
Next intChar
End Function
Function CreateCodeFromPassword(ByVal pstrPasswordCode As String) As String
' Generator free to use
Dim pwLen As Integer
Dim scp As String ' String Code Position, for formatting "0" or "00"
Dim icp As Integer ' marker if pwLen < 10 or > 10
Dim intCode As Integer
Dim arrintShifts() As Integer
Dim arrlngCharCode() As Long
Dim pw() As String
Dim Temp As Variant
Dim arnd() As Variant
Dim irnd As Variant
Randomize
' Initialise Arrays
pwLen = Len(pstrPasswordCode) - 1 ' Array Index starts with 0
scp = IIf(pwLen < 10, "0", "00")
' Create odd/even marker if we have 1 (odd) or 2 (even) byte index digits (scp), values between 0 and 9
icp = IIf(pwLen < 10, Int(Rnd() * 5 + 1) * 2 - 1, Int(Rnd() * 5 + 1) * 2)
ReDim arrintShifts(pwLen)
ReDim arrlngCharCode(pwLen)
ReDim pw(pwLen)
ReDim arnd(pwLen)
For intCode = 0 To pwLen
arnd(intCode) = intCode
Next intCode
' randomize the indizes to bring the code into a random order
For intCode = LBound(arnd) To UBound(arnd)
irnd = CLng(((UBound(arnd) - intCode) * Rnd) + intCode)
If intCode <> irnd Then
Temp = arnd(intCode)
arnd(intCode) = arnd(irnd)
arnd(irnd) = Temp
End If
Next intCode
'by getting the charcodes of these values, you create the password
For intCode = 0 To pwLen
'get characters
pw(intCode) = Mid(pstrPasswordCode, intCode + 1, 1)
'and store -8 to -1 into 0-7 (for additional obfuscation)
arrintShifts(intCode) = intCode - (pwLen + 1)
Next intCode
' Search for the random index and throw the shifted code at this position
For intCode = 0 To pwLen
arrlngCharCode(Application.Match(intCode, arnd, False) - 1) = AscB(pw(intCode)) - arrintShifts(intCode)
Next intCode
' Chain All Codes, combination of arnd(intcode) and arrlngCharCode(intcode) gives the random order
CreateCodeFromPassword = ""
For intCode = 0 To pwLen
CreateCodeFromPassword = CreateCodeFromPassword & Format(arnd(intCode), scp) & Format(arrlngCharCode(intCode), "000")
Next intCode
CreateCodeFromPassword = CreateCodeFromPassword & icp
End Function
Obfuscated version
'VBA code protection using: www.excel-pratique.com/en/vba_tricks/vba-obfuscator.php
Function CreatePasswordFromCode(ByVal z4891679d877f1da36647b21d6197fbfd As String) As String
Dim b2da54ddb60c93bf346493d7e08bc6d08 As Integer
Dim bf56f94eb6ed9a658e82e88591237324d As Integer
Dim bec732ae8e18b7b2ff2e9ccd058f3e8fc As Integer
Dim m06993036154505accc9ce092bdb57b17() As Integer
Dim b8026f9f8f7fe86372be0799d8c9c6691() As Long
Dim q24471047c7a6e466b78de3c6ae66f20f As String
Dim t5f443e88a552a3f943275f985dde03ca As Integer
t5f443e88a552a3f943275f985dde03ca = IIf(Right(z4891679d877f1da36647b21d6197fbfd, 1) Mod 2 = 0, 5, 4)
z4891679d877f1da36647b21d6197fbfd = Left(z4891679d877f1da36647b21d6197fbfd, Len(z4891679d877f1da36647b21d6197fbfd) - IIf(Right(z4891679d877f1da36647b21d6197fbfd, 1) Mod 2 = 0, 1, 1))
b2da54ddb60c93bf346493d7e08bc6d08 = Len(z4891679d877f1da36647b21d6197fbfd) / t5f443e88a552a3f943275f985dde03ca - 1
ReDim m06993036154505accc9ce092bdb57b17(b2da54ddb60c93bf346493d7e08bc6d08)
ReDim b8026f9f8f7fe86372be0799d8c9c6691(b2da54ddb60c93bf346493d7e08bc6d08)
bf56f94eb6ed9a658e82e88591237324d = 0
bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To b2da54ddb60c93bf346493d7e08bc6d08
m06993036154505accc9ce092bdb57b17(bec732ae8e18b7b2ff2e9ccd058f3e8fc) = bec732ae8e18b7b2ff2e9ccd058f3e8fc - (b2da54ddb60c93bf346493d7e08bc6d08 + 1)
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
For bf56f94eb6ed9a658e82e88591237324d = 0 To b2da54ddb60c93bf346493d7e08bc6d08
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To b2da54ddb60c93bf346493d7e08bc6d08
If CInt(Mid(z4891679d877f1da36647b21d6197fbfd, bec732ae8e18b7b2ff2e9ccd058f3e8fc * t5f443e88a552a3f943275f985dde03ca + 1, t5f443e88a552a3f943275f985dde03ca - 3)) = bf56f94eb6ed9a658e82e88591237324d Then
b8026f9f8f7fe86372be0799d8c9c6691(bf56f94eb6ed9a658e82e88591237324d) = (Mid(z4891679d877f1da36647b21d6197fbfd, (bec732ae8e18b7b2ff2e9ccd058f3e8fc + 1) * t5f443e88a552a3f943275f985dde03ca - 2, 3) + m06993036154505accc9ce092bdb57b17(bf56f94eb6ed9a658e82e88591237324d))
Exit For
End If
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
Next bf56f94eb6ed9a658e82e88591237324d
CreatePasswordFromCode = ""
For bf56f94eb6ed9a658e82e88591237324d = 0 To b2da54ddb60c93bf346493d7e08bc6d08
CreatePasswordFromCode = CreatePasswordFromCode & Chr(b8026f9f8f7fe86372be0799d8c9c6691(bf56f94eb6ed9a658e82e88591237324d))
Next bf56f94eb6ed9a658e82e88591237324d
End Function
Function CreateCodeFromPassword(ByVal z4891679d877f1da36647b21d6197fbfd As String) As String
Dim qe564274d6cab7b91a3393ef092dac78f As Integer
Dim b330c8da5472f3c36b801671ef5a54797 As String
Dim t5f443e88a552a3f943275f985dde03ca As Integer
Dim bec732ae8e18b7b2ff2e9ccd058f3e8fc As Integer
Dim m06993036154505accc9ce092bdb57b17() As Integer
Dim b8026f9f8f7fe86372be0799d8c9c6691() As Long
Dim b343223dcae485b35af2792c7dd91f92b() As String
Dim e0d4cf763c9da42470a729a29b30d7d50 As Variant
Dim b41d8f2e79c0e09113beb7629aa0d8c48() As Variant
Dim b42a57d0c121b9fe34a74143aa279157c As Variant
Randomize
qe564274d6cab7b91a3393ef092dac78f = Len(z4891679d877f1da36647b21d6197fbfd) - 1
b330c8da5472f3c36b801671ef5a54797 = IIf(qe564274d6cab7b91a3393ef092dac78f < 10, "0", "00")
t5f443e88a552a3f943275f985dde03ca = IIf(qe564274d6cab7b91a3393ef092dac78f < 10, Int(Rnd() * 5 + 1) * 2 - 1, Int(Rnd() * 5 + 1) * 2)
ReDim m06993036154505accc9ce092bdb57b17(qe564274d6cab7b91a3393ef092dac78f)
ReDim b8026f9f8f7fe86372be0799d8c9c6691(qe564274d6cab7b91a3393ef092dac78f)
ReDim b343223dcae485b35af2792c7dd91f92b(qe564274d6cab7b91a3393ef092dac78f)
ReDim b41d8f2e79c0e09113beb7629aa0d8c48(qe564274d6cab7b91a3393ef092dac78f)
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To qe564274d6cab7b91a3393ef092dac78f
b41d8f2e79c0e09113beb7629aa0d8c48(bec732ae8e18b7b2ff2e9ccd058f3e8fc) = bec732ae8e18b7b2ff2e9ccd058f3e8fc
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = LBound(b41d8f2e79c0e09113beb7629aa0d8c48) To UBound(b41d8f2e79c0e09113beb7629aa0d8c48)
b42a57d0c121b9fe34a74143aa279157c = CLng(((UBound(b41d8f2e79c0e09113beb7629aa0d8c48) - bec732ae8e18b7b2ff2e9ccd058f3e8fc) * Rnd) + bec732ae8e18b7b2ff2e9ccd058f3e8fc)
If bec732ae8e18b7b2ff2e9ccd058f3e8fc <> b42a57d0c121b9fe34a74143aa279157c Then
e0d4cf763c9da42470a729a29b30d7d50 = b41d8f2e79c0e09113beb7629aa0d8c48(bec732ae8e18b7b2ff2e9ccd058f3e8fc)
b41d8f2e79c0e09113beb7629aa0d8c48(bec732ae8e18b7b2ff2e9ccd058f3e8fc) = b41d8f2e79c0e09113beb7629aa0d8c48(b42a57d0c121b9fe34a74143aa279157c)
b41d8f2e79c0e09113beb7629aa0d8c48(b42a57d0c121b9fe34a74143aa279157c) = e0d4cf763c9da42470a729a29b30d7d50
End If
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To qe564274d6cab7b91a3393ef092dac78f
b343223dcae485b35af2792c7dd91f92b(bec732ae8e18b7b2ff2e9ccd058f3e8fc) = Mid(z4891679d877f1da36647b21d6197fbfd, bec732ae8e18b7b2ff2e9ccd058f3e8fc + 1, 1)
m06993036154505accc9ce092bdb57b17(bec732ae8e18b7b2ff2e9ccd058f3e8fc) = bec732ae8e18b7b2ff2e9ccd058f3e8fc - (qe564274d6cab7b91a3393ef092dac78f + 1)
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To qe564274d6cab7b91a3393ef092dac78f
b8026f9f8f7fe86372be0799d8c9c6691(Application.Match(bec732ae8e18b7b2ff2e9ccd058f3e8fc, b41d8f2e79c0e09113beb7629aa0d8c48, False) - 1) = AscB(b343223dcae485b35af2792c7dd91f92b(bec732ae8e18b7b2ff2e9ccd058f3e8fc)) - m06993036154505accc9ce092bdb57b17(bec732ae8e18b7b2ff2e9ccd058f3e8fc)
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
CreateCodeFromPassword = ""
For bec732ae8e18b7b2ff2e9ccd058f3e8fc = 0 To qe564274d6cab7b91a3393ef092dac78f
CreateCodeFromPassword = CreateCodeFromPassword & Format(b41d8f2e79c0e09113beb7629aa0d8c48(bec732ae8e18b7b2ff2e9ccd058f3e8fc), b330c8da5472f3c36b801671ef5a54797) & Format(b8026f9f8f7fe86372be0799d8c9c6691(bec732ae8e18b7b2ff2e9ccd058f3e8fc), "000")
Next bec732ae8e18b7b2ff2e9ccd058f3e8fc
CreateCodeFromPassword = CreateCodeFromPassword & t5f443e88a552a3f943275f985dde03ca
End Function

Assign an integer variable to an integer variable and change name dynamic

Dim LastNumber as Integer = 1
Dim num_0() as Integer = {1, 2, 3, 4, 5}
Dim num_1() as Integer = {6, 7, 8, 9, 10}
Dim num_2() as Integer = {20, 21, 14, 36, 0}
Dim y() As Integer
y(0) = num_0(2)
When I use this code it executes perfectly
But the problem is I want to change the "0" in num_0(2)
When I do...
y(0) = num_ & LastNumber & (2)
This doesnt work
Or
y(0) = ("num_" & LastNumber & "(2)")
This gives me an error that converting a string to an integer is not possible
My question is How can I replace the "0" in num_0(2) with the LastNumber integer variable... so it reads the "8" out of the array num_1(2)
You can use multidimensional array (AKA rectangular array):
Dim num As Integer(,) = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {20, 21, 14, 36, 0} }
y(0) = num(LastNumber, 2)
or jagged array (array of arrays) :
Dim num As Integer()() = { ({1, 2, 3, 4, 5}), ({6, 7, 8, 9, 10}), ({20, 21, 14, 36, 0}) }
y(0) = num(LastNumber)(2)

VB.NET - How to calculate the parity bit of a byte array

What is the most efficient way calculate the parity bit (if the number of active bits are odd or even) in a byte array? I have though about iterating through all the bits and summing up the active bits, but that would be very impractical purely based on the number of iterations required on larger byte arrays/files.
For your convenience (and my curiosity), I have done some timing tests with a parity lookup table compared to the other two methods suggested so far:
Module Module1
Dim rand As New Random
Dim parityLookup(255) As Integer
Sub SetUpParityLookup()
' setBitsCount data from http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
Dim setBitsCount = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
}
For i = 0 To 255
parityLookup(i) = setBitsCount(i) And 1
Next
End Sub
' Method using lookup table
Function ParityOfArray(a() As Byte) As Integer
Dim parity As Integer = 0 ' use an Integer because they are faster
For i = 0 To a.Length - 1
parity = parity Xor parityLookup(a(i))
Next
Return parity
End Function
' Method by Alireza
Function ComputeParity(bytes() As Byte) As Byte
Dim parity As Boolean = False
For i As Integer = 0 To bytes.Length - 1
Dim b As Byte = bytes(i)
While b <> 0
parity = Not parity
b = CByte(b And (b - 1))
End While
Next
Return Convert.ToByte(parity)
End Function
' Method by dbasnett
Function CountBits(byteArray As Byte()) As Integer
Dim rv As Integer = 0
For Each b As Byte In byteArray
Dim count As Integer = b
count = ((count >> 1) And &H55) + (count And &H55)
count = ((count >> 2) And &H33) + (count And &H33)
count = ((count >> 4) And &HF) + (count And &HF)
rv += count
Next
Return rv
End Function
Sub FillWithRandomBytes(ByRef a() As Byte)
rand.NextBytes(a)
End Sub
Sub Main()
SetUpParityLookup()
Dim nBytes = 10000
Dim a(nBytes - 1) As Byte
FillWithRandomBytes(a)
Dim p As Integer
Dim sw As New Stopwatch
sw.Start()
p = ParityOfArray(a)
sw.Stop()
Console.WriteLine("ParityOfArray - Parity: {0} Time: {1}", p, sw.ElapsedTicks)
sw.Restart()
p = ComputeParity(a)
sw.Stop()
Console.WriteLine("ComputeParity - Parity: {0} Time: {1}", p, sw.ElapsedTicks)
sw.Restart()
p = CountBits(a)
sw.Stop()
' Note that the value returned from CountBits should be And-ed with 1.
Console.WriteLine("CountBits - Parity: {0} Time: {1}", p And 1, sw.ElapsedTicks)
Console.ReadLine()
End Sub
End Module
Typical ouput:
ParityOfArray - Parity: 0 Time: 386
ComputeParity - Parity: 0 Time: 1014
CountBits - Parity: 0 Time: 695
An efficient way to do this is to use the x & (x - 1) operation in a loop, until x becomes zero. This way you will loop only by the number of bits set to 1.
In VB.NET for a byte array:
Function ComputeParity(bytes() As Byte) As Byte
Dim parity As Boolean = False
For i As Integer = 0 To bytes.Length - 1
Dim b As Byte = bytes(i)
While b <> 0
parity = Not parity
b = b And (b - 1)
End While
Next
Return Convert.ToByte(parity)
End Function
Here is a function that counts bits.
Private Function CountBits(byteArray As Byte()) As Integer
Dim rv As Integer = 0
For x As Integer = 0 To byteArray.Length - 1
Dim b As Byte = byteArray(x)
Dim count As Integer = b
count = ((count >> 1) And &H55) + (count And &H55)
count = ((count >> 2) And &H33) + (count And &H33)
count = ((count >> 4) And &HF) + (count And &HF)
rv += count
Next
Return rv
End Function
Note: this code came from a collection of bit twiddling hacks I found some years ago. I converted it to VB.