Dear experts,
I have a query on how to dynamically interchange the position of a character variable in a way that receiver of my file can re-generate the original values.
Sample Input and Output is as follows:
Input | Output |
Michael | Lhameci |
Jack@gmail.com | kcja@gmail.com |
AO987JJ | 9J78JOA |
9650234567 | 6953035947 |
Thanks in advance..
You can permute the string characters following a random sequence set by a secret seed, and then reverse the permutation using the same seed:
data have;
input InputStr :$20.;
datalines;
Michael
Jack@gmail.com
AO987JJ
9650234567
;
%let seed=736435; /* Secret code */
/* Blurring the strings */
data blur;
retain seed &seed.;
set have;
isEmail = index(InputStr, "@") > 1;
length str $20;
if isEmail then str = scan(InputStr,1,"@");
else str = InputStr;
isName = str = propCase(str);
array pos{20};
do i = 1 to length(str);
pos{i} = i;
end;
/* Could be coded with a macro I guess, to accomodate longer strings ... */
select (length(str));
when ( 2) call ranperm(seed, of pos1-pos2);
when ( 3) call ranperm(seed, of pos1-pos3);
when ( 4) call ranperm(seed, of pos1-pos4);
when ( 5) call ranperm(seed, of pos1-pos5);
when ( 6) call ranperm(seed, of pos1-pos6);
when ( 7) call ranperm(seed, of pos1-pos7);
when ( 8) call ranperm(seed, of pos1-pos8);
when ( 9) call ranperm(seed, of pos1-pos9);
when (10) call ranperm(seed, of pos1-pos10);
when (11) call ranperm(seed, of pos1-pos11);
when (12) call ranperm(seed, of pos1-pos12);
when (13) call ranperm(seed, of pos1-pos13);
when (14) call ranperm(seed, of pos1-pos14);
when (15) call ranperm(seed, of pos1-pos15);
when (16) call ranperm(seed, of pos1-pos16);
when (17) call ranperm(seed, of pos1-pos17);
when (18) call ranperm(seed, of pos1-pos18);
when (19) call ranperm(seed, of pos1-pos19);
when (20) call ranperm(seed, of pos1-pos20);
otherwise;
end;
length OutputStr $20;
do i = 1 to length(str);
substr(outputStr, i, 1) = substr(str, pos{i}, 1);
end;
if isName then OutputStr = propCase(OutputStr);
if isEmail then OutputStr = catx("@", OutputStr, scan(InputStr, 2, "@"));
drop i seed isName isEmail str pos:;
run;
/* Recovering the strings, using the same secret code */
data want;
retain seed &seed.;
set blur;
isEmail = index(OutputStr, "@") > 1;
length str $20;
if isEmail then str = scan(OutputStr,1,"@");
else str = OutputStr;
isName = str = propCase(str);
array pos{20};
do i = 1 to length(str);
pos{i} = i;
end;
select (length(str));
when ( 2) call ranperm(seed, of pos1-pos2);
when ( 3) call ranperm(seed, of pos1-pos3);
when ( 4) call ranperm(seed, of pos1-pos4);
when ( 5) call ranperm(seed, of pos1-pos5);
when ( 6) call ranperm(seed, of pos1-pos6);
when ( 7) call ranperm(seed, of pos1-pos7);
when ( 8) call ranperm(seed, of pos1-pos8);
when ( 9) call ranperm(seed, of pos1-pos9);
when (10) call ranperm(seed, of pos1-pos10);
when (11) call ranperm(seed, of pos1-pos11);
when (12) call ranperm(seed, of pos1-pos12);
when (13) call ranperm(seed, of pos1-pos13);
when (14) call ranperm(seed, of pos1-pos14);
when (15) call ranperm(seed, of pos1-pos15);
when (16) call ranperm(seed, of pos1-pos16);
when (17) call ranperm(seed, of pos1-pos17);
when (18) call ranperm(seed, of pos1-pos18);
when (19) call ranperm(seed, of pos1-pos19);
when (20) call ranperm(seed, of pos1-pos20);
otherwise;
end;
length SecretStr $20;
do i = 1 to length(str);
substr(SecretStr, pos{i}, 1) = substr(str, i, 1);
end;
if isName then SecretStr = propCase(SecretStr);
if isEmail then SecretStr = catx("@", SecretStr, scan(OutputStr, 2, "@"));
drop i seed isName isEmail str pos:;
run;
title "Blurred and deblurred strings";
proc print data=want; run;
Blurred and deblurred strings Obs. InputStr OutputStr SecretStr 1 Michael Acemhil Michael 2 Jack@gmail.com Cjak@gmail.com Jack@gmail.com 3 AO987JJ 78AO9JJ AO987JJ 4 9650234567 4620673559 9650234567
How many other exceptions to scrambling the entire string do you have? And what do they look like if they are not email addresses?
Do you mean a random approach?
And where did the second J go in your third example? If characters are to be substituted you need to state any rules involved.
How do you expect the other person to use this?
What is your actual business problem? Also interchanging character positions isn't masking, it is a very basic form of encryption. If you simply want to exchange data with other parties in encrypted form, why not just use an encryption tool? It is so much easier than doing what you are suggesting and a whole lot more secure too.
You can permute the string characters following a random sequence set by a secret seed, and then reverse the permutation using the same seed:
data have;
input InputStr :$20.;
datalines;
Michael
Jack@gmail.com
AO987JJ
9650234567
;
%let seed=736435; /* Secret code */
/* Blurring the strings */
data blur;
retain seed &seed.;
set have;
isEmail = index(InputStr, "@") > 1;
length str $20;
if isEmail then str = scan(InputStr,1,"@");
else str = InputStr;
isName = str = propCase(str);
array pos{20};
do i = 1 to length(str);
pos{i} = i;
end;
/* Could be coded with a macro I guess, to accomodate longer strings ... */
select (length(str));
when ( 2) call ranperm(seed, of pos1-pos2);
when ( 3) call ranperm(seed, of pos1-pos3);
when ( 4) call ranperm(seed, of pos1-pos4);
when ( 5) call ranperm(seed, of pos1-pos5);
when ( 6) call ranperm(seed, of pos1-pos6);
when ( 7) call ranperm(seed, of pos1-pos7);
when ( 8) call ranperm(seed, of pos1-pos8);
when ( 9) call ranperm(seed, of pos1-pos9);
when (10) call ranperm(seed, of pos1-pos10);
when (11) call ranperm(seed, of pos1-pos11);
when (12) call ranperm(seed, of pos1-pos12);
when (13) call ranperm(seed, of pos1-pos13);
when (14) call ranperm(seed, of pos1-pos14);
when (15) call ranperm(seed, of pos1-pos15);
when (16) call ranperm(seed, of pos1-pos16);
when (17) call ranperm(seed, of pos1-pos17);
when (18) call ranperm(seed, of pos1-pos18);
when (19) call ranperm(seed, of pos1-pos19);
when (20) call ranperm(seed, of pos1-pos20);
otherwise;
end;
length OutputStr $20;
do i = 1 to length(str);
substr(outputStr, i, 1) = substr(str, pos{i}, 1);
end;
if isName then OutputStr = propCase(OutputStr);
if isEmail then OutputStr = catx("@", OutputStr, scan(InputStr, 2, "@"));
drop i seed isName isEmail str pos:;
run;
/* Recovering the strings, using the same secret code */
data want;
retain seed &seed.;
set blur;
isEmail = index(OutputStr, "@") > 1;
length str $20;
if isEmail then str = scan(OutputStr,1,"@");
else str = OutputStr;
isName = str = propCase(str);
array pos{20};
do i = 1 to length(str);
pos{i} = i;
end;
select (length(str));
when ( 2) call ranperm(seed, of pos1-pos2);
when ( 3) call ranperm(seed, of pos1-pos3);
when ( 4) call ranperm(seed, of pos1-pos4);
when ( 5) call ranperm(seed, of pos1-pos5);
when ( 6) call ranperm(seed, of pos1-pos6);
when ( 7) call ranperm(seed, of pos1-pos7);
when ( 8) call ranperm(seed, of pos1-pos8);
when ( 9) call ranperm(seed, of pos1-pos9);
when (10) call ranperm(seed, of pos1-pos10);
when (11) call ranperm(seed, of pos1-pos11);
when (12) call ranperm(seed, of pos1-pos12);
when (13) call ranperm(seed, of pos1-pos13);
when (14) call ranperm(seed, of pos1-pos14);
when (15) call ranperm(seed, of pos1-pos15);
when (16) call ranperm(seed, of pos1-pos16);
when (17) call ranperm(seed, of pos1-pos17);
when (18) call ranperm(seed, of pos1-pos18);
when (19) call ranperm(seed, of pos1-pos19);
when (20) call ranperm(seed, of pos1-pos20);
otherwise;
end;
length SecretStr $20;
do i = 1 to length(str);
substr(SecretStr, pos{i}, 1) = substr(str, i, 1);
end;
if isName then SecretStr = propCase(SecretStr);
if isEmail then SecretStr = catx("@", SecretStr, scan(OutputStr, 2, "@"));
drop i seed isName isEmail str pos:;
run;
title "Blurred and deblurred strings";
proc print data=want; run;
Blurred and deblurred strings Obs. InputStr OutputStr SecretStr 1 Michael Acemhil Michael 2 Jack@gmail.com Cjak@gmail.com Jack@gmail.com 3 AO987JJ 78AO9JJ AO987JJ 4 9650234567 4620673559 9650234567
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.