Hello SAS friends, I am new to SAS and I am still learning. I am in need of a program that generates a random ID. I found a script on this forum and made a few changes and it works, but it is not quite what I need. I need this script to force the random generating ID to Always use at least 1 upper case letter, 1 number and 1 special character (# or @). Is this possible? Here is the code I am using.
data temp (keep=id_out); allowed="123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz#@"; num_ids=1; idlen=8; array done{100} $200.; length my_id $6; num_allowed=length(strip(allowed)); i=1; do until (i=num_ids+1); do j=1 to 6; temp=ceil((num_allowed * rand("uniform"))); substr(my_id,j,1)=substr(allowed,temp,1); end; if whichc(my_id,of done{*})=0 then do; done{i}=my_id; i=i+1; id_out=my_id; output; end; end; run;
Any help would be great!
Below should do what you're asking for.
%let chars=123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz#@;
%let special=#@;
%let id_len=6;
data want(drop=_:);
length id_out $ &id_len;
do _i=1 to &id_len;
_idx=rand('integer',1,%length(&chars));
id_out=cats(id_out,substr("&chars",_idx,1));
end;
do until(_check=3);
_check=0;
/* digit 1 to 9? */
if prxmatch('/\d/',id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',rank('1'),rank('9'));
substr(id_out, _idx, 1)=byte(_idy);
end;
else _check=sum(_check,1);
/* upper case letter? */
if prxmatch('/[A-Z]/',id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',rank('A'),rank('Z'));
substr(id_out, _idx, 1)=byte(_idy);
end;
else _check=sum(_check,1);
/* special char? */
if prxmatch("/[&special]/",id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',1,%length(&special));
substr(id_out, _idx, 1)=substr("&special",_idy,1);
end;
else _check=sum(_check,1);
end;
output;
stop;
run;
proc print;
run;
Below should do what you're asking for.
%let chars=123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz#@;
%let special=#@;
%let id_len=6;
data want(drop=_:);
length id_out $ &id_len;
do _i=1 to &id_len;
_idx=rand('integer',1,%length(&chars));
id_out=cats(id_out,substr("&chars",_idx,1));
end;
do until(_check=3);
_check=0;
/* digit 1 to 9? */
if prxmatch('/\d/',id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',rank('1'),rank('9'));
substr(id_out, _idx, 1)=byte(_idy);
end;
else _check=sum(_check,1);
/* upper case letter? */
if prxmatch('/[A-Z]/',id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',rank('A'),rank('Z'));
substr(id_out, _idx, 1)=byte(_idy);
end;
else _check=sum(_check,1);
/* special char? */
if prxmatch("/[&special]/",id_out)<1 then
do;
_idx=rand('integer',1,&id_len);
_idy=rand('integer',1,%length(&special));
substr(id_out, _idx, 1)=substr("&special",_idy,1);
end;
else _check=sum(_check,1);
end;
output;
stop;
run;
proc print;
run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.