用辅音代替辅音,用元音代替元音,用数字代替数字:
import java.util.Random;
public class Example {
static char randomChar (Random r, String cs, boolean uppercase) {
char c = cs.charAt(r.nextInt(cs.length()));
return uppercase ? Character.toUpperCase(c) : c;
}
static String mask (String str, int seed) {
final String cons = "bcdfghjklmnpqrstvwxz";
final String vowel = "aeiouy";
final String digit = "0123456789";
Random r = new Random(seed);
char data[] = str.toCharArray();
for (int n = 0; n < data.length; ++ n) {
char ln = Character.toLowerCase(data[n]);
if (cons.indexOf(ln) >= 0)
data[n] = randomChar(r, cons, ln != data[n]);
else if (vowel.indexOf(ln) >= 0)
data[n] = randomChar(r, vowel, ln != data[n]);
else if (digit.indexOf(ln) >= 0)
data[n] = randomChar(r, digit, ln != data[n]);
}
return new String(data);
}
public static void main (String[] args) {
System.out.println(mask("John Doe, 534 West Street, Wherever, XY. (888) 535-3593. 399-35-3535", 0));
}
}
产生输出:
Bumk Tyy, 194 Wyrd Tggoyb, Flikibod, QY。 (557) 722-5385。 055-08-1462
来自输入:
John Doe,西街 534 号,无论何处,XY。 (888) 535-3593。 399-35-3535
由您来生成种子。如果您想保证相同的输入始终产生相同的输出,请使用基于输入数据(例如校验和)的种子以及一致的 RNG。
可以通过使用字符类表而不是例如vowel.indexOf()。可以进行进一步的微优化(例如,重新使用Random,仅在char[] 上运行并减少新的String 分配等)
完全支持 Unicode 会遇到很大的困难。屏蔽也不会改变组件的长度。
总的来说,我认为这是一个很差但至少还算有趣的算法。
我认为您不明白您所要求的(看起来真实的输出)超出了正常加密主题的范围,并且不适合“效率”,因为需要进行一些形态分析才能产生有意义的结果(同样,国际化使这显着复杂化)。