Question : Password Verify Funcation

I am trying to create a password verify function that should meet the criteria of :
1) Must have at least 2 alpha characters
2) Must have at least 2 numeric characters
3) Must have at least 2 out of the following three (#,$, _) special characters
4) Must be at least 8 characters long
5) Must not be too easy like 'welcome', 'database', 'account', 'user', 'password',
        'oracle', 'computer', 'abcd'
My code does not seem to be working as expected. When I create a password like qwer1234, the error i get is "Password must contain at least two letters". I should get the error , Password must contain at least two out of these three special characters #, $, _
Please help me fix this asap.
Kamal



Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
CREATE OR REPLACE FUNCTION PWD_NON_SYS_1
(username varchar2,
  password varchar2,
  old_password varchar2)
  RETURN boolean IS 
   n boolean;
   m integer;
   differ integer;
   isdigit boolean;
   ischar  boolean;
   ispunct boolean;
   digitarray varchar2(20);
   punctarray varchar2(25);
   chararray varchar2(52);
 
BEGIN 
   digitarray:= '0123456789';
   chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
   punctarray:='#$_'; 
 
-- Check if the password is same as the username 
   IF NLS_LOWER(password) = NLS_LOWER(username) THEN 
     raise_application_error(-20001, 'Password same as or similar to user'); 
   END IF; 
 
-- Check for the minimum length of the password
   IF length(password) < 8 THEN
      raise_application_error(-20002, 'Password length less than 8 characters');
   END IF;
 
-- Check if the password is too simple. A dictionary of words may be 
-- maintained and a check may be made so as not to allow the words 
-- that are too simple for the password. 
   IF NLS_LOWER(password) IN ('welcome', 'database', 'account', 'user', 'password', 'oracle', 'computer', 'abcd') THEN 
      raise_application_error(-20002, 'Password too simple'); 
   END IF; 
   -- Check if the password contains at least two letters, two digits and two special characters. 
   -- 1. Check for the digit 
      isdigit:=FALSE; 
         m := length(password); 
           FOR i IN 1..10 LOOP 
           FOR j IN 1..m LOOP 
         IF substr(password,j,2) = substr(digitarray,i,2) THEN 
            isdigit:=TRUE; 
             GOTO findchar; 
         END IF; 
      END LOOP; 
   END LOOP; 
 IF isdigit = FALSE THEN 
      raise_application_error(-20003, 'Password must contain at least two digits'); 
   END IF; 
   
-- 2. Check for the character 
   <> 
   ischar:=FALSE; 
   FOR i IN 1..length(chararray) LOOP 
      FOR j IN 1..m LOOP 
         IF substr(password,j,2) = substr(chararray,i,2) THEN 
            ischar:=TRUE; 
             GOTO findpunct; 
         END IF; 
      END LOOP; 
   END LOOP; 
   IF ischar = FALSE THEN 
      raise_application_error(-20003, 'Password must contain at least two letters'); 
   END IF; 
 
   -- 3. Check for the punctuation 
        <> 
   ispunct:=FALSE; 
   FOR i IN 1..length(punctarray) LOOP 
      FOR j IN 1..m LOOP 
         IF substr(password,j,2) = substr(punctarray,i,2) THEN 
            ispunct:=TRUE; 
             GOTO endsearch; 
         END IF; 
      END LOOP; 
   END LOOP; 
   IF ispunct = FALSE THEN 
      raise_application_error(-20003, 'Password must contain at least two out of these three special characters #, $, _'); 
   END IF;
   <> 
   -- Check if the password differs from the previous password by at least 3 letters 
   IF old_password IS NOT NULL THEN 
     differ := length(old_password) - length(password); 
     IF abs(differ) < 3 THEN 
       IF length(password) < length(old_password) THEN 
         m := length(password); 
       ELSE 
         m := length(old_password); 
       END IF; 
       differ := abs(differ); 
       FOR i IN 1..m LOOP 
         IF substr(password,i,1) != substr(old_password,i,1) THEN 
           differ := differ + 1; 
         END IF; 
       END LOOP; 
       IF differ < 3 THEN 
         raise_application_error(-20004, 'Password should differ by at least 3 characters'); 
       END IF; 
     END IF; 
   END IF; 
   -- Everything is fine; return TRUE ; 
   RETURN(TRUE); 
END;
/
Open in New Window Select All

Answer : Password Verify Funcation

yes, you "could" put a list of words there.  but the example words you picked don't make sense.  None of them follow your rules so they wouldn't be allowed anyway.

that's why I moved that check after the other rules and put in an example word that would pass the checks above it but still not be allowed for being too simple

sorry about the expressions,  forgot to include checks of nulls.  fixed below
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
CREATE OR REPLACE FUNCTION pwd_non_sys_1(username        VARCHAR2,
                                         password        VARCHAR2,
                                         old_password    VARCHAR2)
    RETURN BOOLEAN
IS
    differ   INTEGER;
BEGIN
    -- Check if the password is same as the username
    IF NLS_LOWER(password) = NLS_LOWER(username) THEN
        raise_application_error(-20001, 'Password same as or similar to user');
    END IF;
 
    -- Check for the minimum length of the password
    IF NVL(LENGTH(password), 0) < 8 THEN
        raise_application_error(-20002, 'Password length less than 8 characters');
    END IF;
 
 
    IF NVL(LENGTH(REGEXP_REPLACE(password, '[^0-9]', NULL)), 0) < 2 THEN
        raise_application_error(-20003, 'Password must contain at least two digits');
    END IF;
 
 
    IF NVL(LENGTH(REGEXP_REPLACE(password, '[^a-zA-Z]', NULL)), 0) < 2 THEN
        raise_application_error(-20003, 'Password must contain at least two letters');
    END IF;
 
 
    IF NVL(LENGTH(REGEXP_REPLACE(password, '[^#$_]', NULL)), 0) < 2 THEN
        raise_application_error(
            -20003,
            'Password must contain at least two out of these three special characters #, $, _'
        );
    END IF;
 
    -- Check if the password is too simple. A dictionary of words may be
    -- maintained and a check may be made so as not to allow the words
    -- that are too simple for the password.
    IF NLS_LOWER(password) IN ('password99##') THEN
        raise_application_error(-20002, 'Password too simple');
    END IF;
 
 
    -- Check if the password differs from the previous password by at least 3 letters
    IF old_password IS NOT NULL THEN
        differ   := LENGTH(old_password) - LENGTH(password);
 
        IF ABS(differ) < 3 THEN
            differ   := ABS(differ);
 
            FOR i IN 1 .. LEAST(LENGTH(password), LENGTH(old_password))
            LOOP
                IF SUBSTR(password, i, 1) != SUBSTR(old_password, i, 1) THEN
                    differ   := differ + 1;
                END IF;
            END LOOP;
 
            IF differ < 3 THEN
                raise_application_error(-20004, 'Password should differ by at least 3 characters');
            END IF;
        END IF;
    END IF;
 
    -- Everything is fine; return TRUE ;
    RETURN TRUE;
END;
/
Open in New Window Select All
Random Solutions  
 
programming4us programming4us