Sea*_*oyd 7 java string encryption algorithm
我想实现一个简单的替换密码来掩盖URL中的私有ID.
我知道我的ID会是什么样子(大写ASCII字母,数字和下划线的组合),它们会很长,因为它们是组合键.我想使用更长的字母来缩短生成的代码(我想使用大写和小写的ASCII字母,数字和其他内容).所以我输入的字母表就是
[A-Z0-9_] (37 chars)
Run Code Online (Sandbox Code Playgroud)
我的外传字母表将是
[A-Za-z0-9] (62 chars)
Run Code Online (Sandbox Code Playgroud)
因此可以获得几乎50%合理压缩量的压缩.
假设我的网址如下所示:
/my/page/GFZHFFFZFZTFZTF_24_F34
Run Code Online (Sandbox Code Playgroud)
而我希望它们看起来像这样:
/my/page/Ft32zfegZFV5
Run Code Online (Sandbox Code Playgroud)
显然,两个数组都会被洗牌以带来一些随机顺序.
这不一定是安全的.如果有人弄清楚:很好,但我不希望这个计划显而易见.
我想要的解决方案是将字符串转换为基数37的整数表示,将基数转换为62并使用第二个字母表来写出该数字.是否有任何类似的示例代码?Integer.parseInt()
有一些类似的逻辑,但硬编码使用标准数字行为.
有任何想法吗?
我使用Java来实现这一点,但任何其他语言的代码或伪代码当然也很有帮助.
莫名其妙地Character.MAX_RADIX
只有 36 位,但你总是可以编写自己的基数转换例程。以下实现不是高性能的,但它应该是一个很好的起点:
import java.math.BigInteger;
public class BaseConvert {
static BigInteger fromString(String s, int base, String symbols) {
BigInteger num = BigInteger.ZERO;
BigInteger biBase = BigInteger.valueOf(base);
for (char ch : s.toCharArray()) {
num = num.multiply(biBase)
.add(BigInteger.valueOf(symbols.indexOf(ch)));
}
return num;
}
static String toString(BigInteger num, int base, String symbols) {
StringBuilder sb = new StringBuilder();
BigInteger biBase = BigInteger.valueOf(base);
while (!num.equals(BigInteger.ZERO)) {
sb.append(symbols.charAt(num.mod(biBase).intValue()));
num = num.divide(biBase);
}
return sb.reverse().toString();
}
static String span(char from, char to) {
StringBuilder sb = new StringBuilder();
for (char ch = from; ch <= to; ch++) {
sb.append(ch);
}
return sb.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
然后您就可以拥有main()
如下所示的测试工具:
public static void main(String[] args) {
final String SYMBOLS_AZ09_ = span('A','Z') + span('0','9') + "_";
final String SYMBOLS_09AZ = span('0','9') + span('A','Z');
final String SYMBOLS_AZaz09 = span('A','Z') + span('a','z') + span('0','9');
BigInteger n = fromString("GFZHFFFZFZTFZTF_24_F34", 37, SYMBOLS_AZ09_);
// let's convert back to base 37 first...
System.out.println(toString(n, 37, SYMBOLS_AZ09_));
// prints "GFZHFFFZFZTFZTF_24_F34"
// now let's see what it looks like in base 62...
System.out.println(toString(n, 62, SYMBOLS_AZaz09));
// prints "ctJvrR5kII1vdHKvjA4"
// now let's test with something we're more familiar with...
System.out.println(fromString("CAFEBABE", 16, SYMBOLS_09AZ));
// prints "3405691582"
n = BigInteger.valueOf(3405691582L);
System.out.println(toString(n, 16, SYMBOLS_09AZ));
// prints "CAFEBABE"
}
Run Code Online (Sandbox Code Playgroud)
BigInteger
如果数字可以超过,可能是最简单的long
char
您可以对符号中的进行洗牌String
,只需坚持一种“秘密”排列即可通常,您不能期望以 62 为基数的字符串比以 36 为基数的字符串短一半左右。这是以Long.MAX_VALUE
10、20 和 30 为基数的:
System.out.format("%s%n%s%n%s%n",
Long.toString(Long.MAX_VALUE, 10), // "9223372036854775807"
Long.toString(Long.MAX_VALUE, 20), // "5cbfjia3fh26ja7"
Long.toString(Long.MAX_VALUE, 30) // "hajppbc1fc207"
);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2248 次 |
最近记录: |