目次
1.既存のデータセットに付与するパターン
1.サンプルデータ
サンプルとして、事前に、以下のようなデータセットを用意します。
data hojin_list;
infile datalines dlm="," dsd missover;
input hojin_name:$200.;
datalines;
日本郵船株式会社
株式会社Mizkan J plus Holdings
公益社団法人福岡医療団
社団医療法人 啓愛会
一般社団法人 北陸地区信用金庫協会
兵庫県弁護士協同組合
学校法人 藤田学園
一般財団法人東北電気保安協会
社会医療法人蘇西厚生会
公益社団法人福岡医療団
田中貴金属労働組合
医療法人社団 友愛病院会
東京海上日動調査サービス共済組合
社会医療法人財団白十字会
オカムラグループ健康保険組合
日本ヒューレット・パッカード合同会社
社団医療法人 啓愛会
;
run;
データセットを開くと以下のようになります。
2.展開例
以下の展開例は、生成するパスワードに含めたくない文字列をマクロexceptとして指定しています。
引数exceptは省略可能なので、マクロexceptは無くても問題ないです。
%macro except;
/*--------------------------------------------------
exceptに指定した文字列を含むPASSWORDは生成されない
※大文字・小文字の区別は無視する
--------------------------------------------------*/
g9h43NmTb5
Nt7tyb8Ae6
YRmY73dgEF
%mend except;
%mk_unique_code(
indata =hojin_list,
obs =,
pw_vname =pw,
pw_length =10,
seed =12345,
moji =ABDEFGHJLMNQRTYabdefghjmnrty23456789,
yomi =%yomi,
except =%except,
outdata =unique_data
);
3.出力結果
以下のように、入力データセットに対し、パスワードが付与されています。
2.任意のOBS数で生成するパターン
1.展開例
既存のデータセットに付与せず、任意のOBS数でパスワードを生成したい場合は、以下のように引数obsにオブザベーション数を指定します。
%mk_unique_code(
indata =,
obs =1000,
pw_vname =pw,
pw_length =10,
seed =12345,
moji =ABDEFGHJLMNQRTYabdefghjmnrty23456789,
yomi =%yomi,
except =,
outdata =unique_data
);
2.出力結果
以下のように、1000オブザベーションのデータセットが生成されます。
3. 参考プログラム
以下は、参考プログラムになります。
右上のコピーボタンを押せば、プログラム全体をコピーできます。
%macro mk_unique_code(indata=, obs=, pw_vname=, pw_length=, seed=, moji=, yomi=, except=, outdata=);
%put --------------------------------------------------;
%put ユニークコードの生成;
%put &=indata; /*ユニークコードを付与するSASデータセット名を指定する(省略する場合は、obsの指定必須)*/
%put &=obs; /*indataを省略する場合にのみ生成OBS数を指定する(indataに指定した場合は機能しない)*/
%put &=pw_vname; /*PASSWORDを格納する変数名を指定*/
%put &=pw_length; /*PASSWORDの文字長さを指定*/
%put &=seed; /*RAND関数のSEED値を指定*/
%put &=moji; /*PASSWORDに使用する半角英数字を指定*/
%put &=yomi; /*PASSWORDに読み仮名を付与する場合は指定する(省略可)*/
%put &=except; /*exceptに指定した文字列を含むPASSWORDは生成されない(省略可)*/
%put &=outdata; /*出力するSASデータセット名を指定*/
%put --------------------------------------------------;
%put ----- OBS数のマクロ変数化 -----;
%if %length(&indata.)>0 %then %do;
data _mk_unique_code_data;
set &indata.;
run;
proc sql noprint;
select count(*) into:__obs from _mk_unique_code_data;
quit;
%end;
%else %do;
%let __obs=&obs.;
%end;
%put ----- ユニークコード&pw_vname.の生成 -----;
data _mk_unique_code_id;
drop __:;
length &pw_vname. $&pw_length..;
if _N_ = 1 then do;
declare hash h1();
h1.definekey("&pw_vname.");
h1.definedone();
end;
__n=length("&moji.");
__kumi=__n**&pw_length.;
put "NOTE:与えられた文字数 = " __n;
put "NOTE:生成できる組み合わせ数 = " __kumi;
call streaminit(&seed.);
do until(__obs=&__obs.);
do until(__okflg=1);
do __i = 1 to &pw_length.;
__r=int(rand("uniform") * length("&moji.") +1);
&pw_vname. = cats(&pw_vname. , char("&moji.", __r));
__e = 1;
__e_cnt=0;
do while(not missing(scan("&except.", __e,, "s")));
if find(&pw_vname., scan("&except.", __e,, "s"), "i") > 0 then __e_cnt + 1;
__e + 1;
end;
if __i = &pw_length. then do;
if h1.check() ne 0 and __e_cnt = 0 then do;
__okflg=1;
h1.add();
output;
__obs+1;
end;
else &pw_vname.="";
end;
end;
end;
end;
run;
%if %length(%superq(yomi)) > 0 %then %do;
%put ----- 読みの追加 -----;
data _mk_unique_code_id;
set _mk_unique_code_id;
length &pw_vname._yomi $32767.;
&pw_vname._yomi=&pw_vname.;
%let _i=1;
%do %while(%qscan(%superq(yomi), &_i.,,s) ne);
&pw_vname._yomi=tranwrd(&pw_vname._yomi, scan("%qscan(%superq(yomi), &_i.,,s)",1,"|"), "・"||scan("%qscan(%superq(yomi), &_i.,,s)",2,"|"));
if substr(&pw_vname._yomi,1,1)="・" then &pw_vname._yomi=substr(&pw_vname._yomi,2);
%let _i=%eval(&_i.+1);
%end;
run;
%end;
%if %length(&indata.)>0 %then %do;
%put ----- 入力データセットにマージして出力 -----;
data &outdata.;
merge
_mk_unique_code_data
_mk_unique_code_id
;
if missing(&pw_vname.) then put "ERROR:正しくユニークコードが生成されていません" +2 (&pw_vname.)(=);
run;
%end;
%else %do;
%put ----- 出力 -----;
data &outdata.;
set _mk_unique_code_id;
if missing(&pw_vname.) then put "ERROR:正しくユニークコードが生成されていません" +2 (&pw_vname.)(=);
run;
%end;
%put ----- 不要データセットの削除 -----;
proc datasets lib=work noprint;
delete _mk_unique_code_:;
quit;
%mend mk_unique_code;
%macro yomi;
/*--------------------------------------------------
半角英数字の読み
--------------------------------------------------*/
A|エー
B|ビー
D|ディー
E|イー
F|エフ
G|ジー
H|エイチ
J|ジェイ
L|エル
M|エム
N|エヌ
Q|キュー
R|アール
T|ティー
Y|ワイ
2|ニ
3|サン
4|ヨン
5|ゴ
6|ロク
7|ナナ
8|ハチ
9|キュウ
A|エー
B|ビー
D|ディー
E|イー
F|エフ
G|ジー
H|エイチ
J|ジェイ
L|エル
M|エム
N|エヌ
Q|キュー
R|アール
T|ティー
Y|ワイ
a|エー
b|ビー
d|ディー
e|イー
f|エフ
g|ジー
h|エイチ
j|ジェイ
m|エム
n|エヌ
r|アール
t|ティー
y|ワイ
2|ニ
3|サン
4|ヨン
5|ゴ
6|ロク
7|ナナ
8|ハチ
9|キュウ
%mend yomi;