Wednesday, November 19, 2014

One more password gen function

I'd like to share function(one of the many=) to generate passwords in PL\SQL. You can easy Google a lot of pretty smart examples, but some time ago I was looking for example and couldn't find password generators with requirements:
1. To be random "enough" 
2. Password must consist of Upper,Lower case and digit.  
Second requirement was strict, even tho it reduces randomnicity of result.
Here my example:

create or replace  function gen_passwd(v_num in varchar2) return varchar2 is  
   v_ret   varchar2(100);  
   v_str   varchar2(100);  
   v_salt  varchar2(100);  
   -- If password contains "@" - connect to Oracle DB with given password drops with ORA-12154  
   -- Excluded "@" from val_spec array  
   val_spec varchar2(100) := q'[!#$%&()*+/<=>?\{}[]]';  
   val_num  varchar2(100) := q'[0123456789]';  
   val_upper varchar2(100) := q'[ABCDEFGHIJKLMNOPQRSTUVWXYZ]';  
   val_lower varchar2(100) := q'[abcdefghijklmnopqrstuvwxyz]';  
  begin  
   if v_num > 30 then  
    raise_application_error(-20008,  
                'Maximum password length in Oracle is 30 characters!');  
   else  
    if v_num < 7 then  
     raise_application_error(-20009,  
                 'Minimum password length must be 7 characters!');  
    end if;  
   end if;  
   v_str := val_num || val_upper || val_lower || val_spec;  
   ---genarate v_num random(ok,pseudo) numbers from array  
   for i in 1 .. v_num loop  
    v_ret := v_ret ||  
         substr(v_str, trunc(dbms_random.value(1, length(v_str))), 1);  
   end loop;  
   --genarate 3 values according to requirements (1 from every array)  
   v_salt := substr(val_num,  
            trunc(dbms_random.value(1, length(val_num))),  
            1) ||  
        substr(val_upper,  
            trunc(dbms_random.value(1, length(val_upper))),  
            1) ||  
        substr(val_lower,  
            trunc(dbms_random.value(1, length(val_lower))),  
            1);  
   ---replace 3 values starting from random position between 1 and v_num-3  
   v_ret := replace(v_ret,  
            substr(v_ret,  
               trunc(dbms_random.value(1, length(v_ret) - 3)),  
               3),  
            v_salt);  
   return v_ret;  
  end;  
 Here we go  
 SQL> declare  
  2  v_out varchar2(30);  
  3 begin  
  4  for i in 7 .. 30 loop  
  5   select gen_passwd(i) into v_out from dual;  
  6   dbms_output.put_line(v_out);  
  7  end loop;  
  8 end;  
  9 /  
 R10BqH<  
 e2Hlsh\C  
 m8CtHODok  
 7Isl(&Ji1v  
 B>!xS4PaUcV  
 f&/3L1YfW#OE  
 5Pi<}Wi[B#CMV  
 Z54Nofc?J{+P3I  
 f3jzrn4P1HrAcJU  
 AkV40Rm#gsTa#ZDU  
 p2wp4IhAD1zT9>o6&  
 [f8IfUCDxy%QYU6z0E  
 pm8Ml>fsTs1dy68#9>T  
 Z+5KnBwe?\}4x2j5f(yK  
 GtUAazUlfh$lzq2n5EhI#  
 tof<}Qpk7Mu<88ae#petls  
 S3vdEU0pSxuJ7*y76Mf6&av  
 Cdf96Yn%%\Ql)q%SiTiwEbwz  
 (Mjpr<AfO8Pu4FS?QkdpF1a>\  
 5SuHLad*a87GeXni<sf4HW*[0D  
 A}dHgu}i>qa9Y><Ky=Ba04Lla6g  
 n(\Q8Ew}hHT#\}Aro=Bn#YICk41v  
 zm#$JK/$}N>W}PtPTHCN2DhG/{3s[  
 CmFI1bmG62zx=b\7Ln/*[Urk&dId39  
 PL/SQL procedure successfully completed  

No comments:

Post a Comment