Problem using IndexOf

I wrote this function to validate the complexity of a password entered by a user. If I enter a password with a leading zero, j returns zero as it should. If I enter a zero anywhere else in the password, j returns -1. How can I work around for this or what did I do wrong?

Private Function PasswordRequires() as Boolean
var b As String = “0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWZYZ”
var c As String
var j As Integer
var a(3) as Integer
for i as Integer = 0 to tfPassword.Text.Length-1
c = tfPassword.Text.Middle(i,1)
j = b.IndexOf(i,c, ComparisonOptions.CaseSensitive)
if j > 35 then // capital letter
a(0) = 1
elseif j > 9 then // lower case letter
a(1) = 1
ElseIf j > -1 then // number
a(2) = 1
Else // other character
a(3) = 1
end if
Next
j = a(0) + a(1) + a(2) + a(3)
if tfPassword.Text.Length > 7 and j > 2 then Return True

var s As String
if Session.LanguageCode.Left(2) = “en” then
s = “Invalid password.” + EndOfLine + "Passwords must be 8 or more characters in length and contain 3 of these 4 "+_
“items: upper case letter, lower case letter, number, special character.”
Else
s = “Contraseña invalida.” + EndOfLine + "Las contraseñas deben tener 8 o más caracteres de longitud y contener 3 "+_
“de estos 4 elementos: letra mayúscula, letra minúscula, número, carácter especial.”
end if
MessageBox s

End Function

I use RegEx to validate password strength.

Protected Function IsPasswordStrongEnough(sPassword as String) as Boolean
  // Check that password is strong enough *for me*
  // This is 7 chars, at least 1 letter, at least one symbol
  
  dim rx as new RegEx
  rx.SearchPattern = "^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{7,}$"
  
  dim rxm as RegExMatch = rx.Search(sPassword)
  return (rxm <> nil)
End Function

Update: The problem in your code is that the further along the password test you go, the further into the source string it starts. You should use better variable names, it will make your code significantly easier to debug.

j = b.IndexOf(i,c, ComparisonOptions.CaseSensitive)

Jump out as wrong when swapping in decent variable names.

iTestIndex = sSourceString.IndexOf(iLoopIteration, sTestCharacter, ComparisonOptions.CaseSensitive)

1 Like

Look at this line:

j = b.IndexOf(i,c, ComparisonOptions.CaseSensitive)

You are searching b starting at subsequent characters after the first character in your password. In other words, the call looks like this:

j = b.IndexOf(1, "0", ComparisonOptions.CaseSensitive)

Since “0” is at position 0, this will return -1.

1 Like

Thanks Tim,
Not used to the new syntax yet. Obviously
j = b.IndexOf(i,c, ComparisonOptions.CaseSensitive)
should have been
j = b.IndexOf(0,c, ComparisonOptions.CaseSensitive)

I started programming in 1961 in Fortran where the only integer variables were i, j, k, l, m and a few others. I’m afraid it’s a habit that is hard to break.