SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
amt11189
Calcite | Level 5

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!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

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;

 

 

View solution in original post

2 REPLIES 2
qatman28
Obsidian | Level 7
I would first select in order 1 random uppercase, 1 random number, 1 random special character, 5 random any characters as array elements e.g. c1-c8. Then randomly sort the array and assign the id by concatenating c1-c8 after randomization. There are many ways to do this in SAS. This approach guarantees your requirements (1 each of the given categories and 8 total).
Patrick
Opal | Level 21

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;

 

 

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 987 views
  • 0 likes
  • 3 in conversation