介绍一个产生随机密码的PL/SQL函数

来源:互联网 发布:东华大学数据库试卷 编辑:程序博客网 时间:2024/05/20 18:55

产生随机密码的基础是产生随机数。

首先,必须有种子。

DBMS_RANDOM.seed(l_seed)

这个种子可以是字符串。为了增加随机性,这个种子字符串可以从Timestamp来获取。

比如,l_seed := to_char(SYSTIMESTAMP,'YYYYDDMMHH24MISSFFFF');

其次,有Value函数。
DBMS_RANDOM.value(mix,max);

给出最小和最大值就可以产生指定范围的随机数。


步骤:

1. 按照函数自变量指定的各类字符(L,小写字母;U-大写字母;D-数字;S-其他符号)的长度,缺省值大家都是1,

   产生一个包含LUDS的字符串,其长度是所要产生的密码的长度。

   比如,要产生的密码长度为8,可以得到LUDSLUDS。

2. 然后把这个字符串洗牌,得到随机的字符串,比如SLDUDLUS。

3. 最后,按以上随机顺序,分别从各种字符的全集中随机取得各个字符,按照步骤2得到的顺序,拼凑一个密码。

   比如 %b9H2aK$。



请看代码:

create or replace function key_gen(  p_len number default 12,  p_use_lcs number default 1,  p_use_ucs number default 1,  p_use_dgt number default 1,  p_use_smb number default 1,  p_use_hex char default 'N',  p_esy_rec char default 'N',  p_smb_str varchar2 default null)return varchar2 isl_use_ptn varchar2(1000);l_use_ptn_len number;l_use_str varchar2(4000);l_use_typ varchar2(10);l_seed varchar2(100);l_lcs varchar2(26):= 'abcdefghijklmnopqrstuvwxyz';l_lcs_len number;l_ucs varchar2(26):= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';l_ucs_len number;l_dgt varchar2(10):= '0123456789';l_dgt_len number;l_smb varchar(50) := q'#!"#$%&'()=~`{+*}<>?_-^\@[;:],./\'#';l_smb_len number;l_hex varchar2(16):= '0123456789abcdef';l_hex_len number;l_key varchar2(4000);l_p1 number;beginif Upper(p_esy_rec) = 'Y' then l_lcs := 'abcdefghijkmnpqrstuvwxyz'; l_ucs := 'ABCDEFGHIJKLMNPQRSTUVWXYZ'; l_dgt := '23456789'; l_smb := q'|!#$%&=+*?-@|';end if;    if p_smb_str is not null then   l_smb :=  p_smb_str;end if;l_lcs_len := lengthb(l_lcs);l_ucs_len := lengthb(l_ucs);l_dgt_len := lengthb(l_dgt);l_smb_len := lengthb(l_smb);l_hex_len := lengthb(l_hex);l_use_ptn := Null;l_use_ptn := l_use_ptn || Trim(rpad(' ',p_use_lcs+1,'L')); -- Put number of Lowercase into patternl_use_ptn := l_use_ptn || Trim(rpad(' ',p_use_ucs+1,'U')); -- Put number of Uppercase into patternl_use_ptn := l_use_ptn || Trim(rpad(' ',p_use_dgt+1,'D')); -- Put number of Digit into patternl_use_ptn := l_use_ptn || Trim(rpad(' ',p_use_smb+1,'S')); -- Put number of Symbol into patternif Upper(p_use_HEX) = 'Y' then -- If hex, excludes others   l_use_ptn := Trim(rpad(' ',p_len+1,'H'));end if;l_use_str := l_use_ptn; -- Compose character type sequence, LUCDSLUCDS....if replace(l_use_ptn,'S','') is not null then   l_use_ptn := replace(l_use_ptn,'S',''); -- Replace S(=symble) if any. Since we need only specified numbers of symbleend if;loop  l_use_str := l_use_str||l_use_ptn;  exit when lengthb(l_use_str)>=p_len;end loop;l_use_str := Substr(l_use_str,1,p_len);--htp.p(l_use_str);l_seed := to_char(SYSTIMESTAMP,'YYYYDDMMHH24MISSFFFF');DBMS_RANDOM.seed(l_seed);-- Randomize the LUDSLUDS sequencefor i in 1 .. p_len loop     l_p1 := ROUND(DBMS_RANDOM.value(1,p_len));  l_use_str := substr(l_use_str,1,l_p1-1)||substr(l_use_str,l_p1+1)||Substr(l_use_str,l_p1,1);end loop;l_key := NULL;for i in 1 .. p_len loop   l_use_typ := substr(l_use_str,i,1);   case l_use_typ    when 'L' then     l_p1 := ROUND(DBMS_RANDOM.value(1,l_lcs_len));     l_key := l_key||substr(l_lcs,l_p1,1);   when 'U' then     l_p1 := ROUND(DBMS_RANDOM.value(1,l_ucs_len));     l_key := l_key||substr(l_ucs,l_p1,1);   when 'D' then     l_p1 := ROUND(DBMS_RANDOM.value(1,l_dgt_len));     l_key := l_key||substr(l_dgt,l_p1,1);   when 'S' then     l_p1 := ROUND(DBMS_RANDOM.value(1,l_smb_len));     l_key := l_key||substr(l_smb,l_p1,1);   when 'H' then      l_p1 := ROUND(DBMS_RANDOM.value(1,l_hex_len));      l_key := l_key||substr(l_hex,l_p1,1);   end case;end loop;return l_key;end;​

说明:

自变量有以下8个,每个都有各自的缺省值。如果不指定任何自变量而执行函数,就可以按照缺省值得到一个随机密码。
这可以满足大多数人的要求。

1. 密码长度,缺省值=12。                               p_len number default 12,   
2. 使用小写字母的最小个数,缺省值=1。0为不使用       p_use_lcs number default 1,
3. 使用大写字母的最小个数,缺省值=1。0为不使用        p_use_ucs number default 1,
4. 使用数字的最小个数,缺省值=1。0为不使用            p_use_dgt number default 1,
5. 使用符号的最小个数,缺省值=1。0为不使用            p_use_smb number default 1,
6. 是否使用16进数产生密码,缺省值=N(不使用)         p_use_hex char default 'N',
   此变量优先度高。如果指定为Y或y,第2-5项变量自动为0.            
7. 是否产生易读的密码,缺省值=N(不使用)             p_esy_rec char default 'N',
   如果指定为Y或y,则不使用容易混淆的字母/数字/符号。比如0/O,1/l,以及一些不易记忆的符号。
8. 用户指定的符号字符串,缺省为Null。                 p_smb_str varchar2 default null
   此变量优先度高。如果指定,将取代函数中预设的符号字符串。这可以使得用户使用自己可以接受的符号,
   比如只使用“#$%&”这4个符号。



使用例子:

1. 完全使用缺省值。产生一个12字符的密码。
select KEY_GEN() FROM DUAL;
KEY_GEN()
v2M02pH/EouB


2. 指定长度,产生一个8字符的密码。
select KEY_GEN(8) FROM DUAL;
KEY_GEN(8)
tNiC%5s1

3.产生一个由16进数组成的密码。长度为12(缺省)。
select KEY_GEN(p_use_hex=>'Y') FROM DUAL;
KEY_GEN(P_USE_HEX=>'Y')
2684dd8cf3ad


4.产生一个包含2个符号的密码,但是符号只包含“#$%&”长度为12(缺省)。
select KEY_GEN(p_smb_str=>'#$%&', p_use_smb=>2) password FROM DUAL;
PASSWORD
lpW1Ux1$S7v%


0 0
原创粉丝点击