我要求将像“ABC123”这样的6个字符串缩短为唯一的4个字符串。它必须是可重复的,以便输入字符串始终生成相同的输出字符串。有没有人有任何理想怎么做?
答案 0 :(得分:8)
无法从6个字符的字符串到4个字符的字符串进行完全唯一的映射。这是简单hash function的示例。由于范围空间小于域空间,因此您必须具有一些哈希collisions。您可以尝试根据您要接受的数据类型最小化冲突次数,但最终不可能将每6个字符串映射到唯一的4个字符串,您将用完4个字符串。
答案 1 :(得分:3)
你需要对输入字符串有一些限制,否则数学将不可避免地咬你。
例如,假设您知道它仅由大写字母和数字组成。因此,有36 ^ 6个可能的输入字符串。
结果需要有更少的限制,例如你允许216个不同的字符(可打印的扩展ascii或类似的东西)。
纯粹巧合,216 ^ 4 = 36 ^ 6,所以你需要的是一个映射。这很容易,只需使用算法将数字表示从一个基数转换为另一个基数。
答案 2 :(得分:1)
不确定是否可以这样做,因为我认为存在一些业务限制(例如用户必须能够输入密钥)。
这个想法是将值“哈希”到较少数量的地方。这需要一个足够大的字符集来处理所有组合。
假设原始密钥不区分大小写,您有26 + 10 = 32,然后提升到第6个唯一组合(2,176,782,336个唯一组合)。要仅使用4个字符进行匹配,您必须使用具有216个唯一字符的字符集,因为216 ^ 6是2,176,782,336,或者第一个数字增加到4,其组合多于带有数字的不区分大小写的键。 (不区分大小写,加上数字只会带你到62)。
如果我们使用标准的美式键盘,我们有26个字母x 2个案例= 52 10个数字 数字键上有10个特殊字符 11个其他特殊字符键* 2 = 22
这是94个唯一字符,或者不到一半的唯一字符,只需要将不区分大小写的6位数代码转换为4位数字即可。现在,在克林贡星球上,键盘要大得多......; - )
如果密钥不区分大小写,则字符集必须扩展为489个唯一字符以适合4位“哈希”。哎哟!
答案 3 :(得分:0)
假设:输入字符串只能包含ASCII十进制值低于128的字符...否则,正如其他人所说,这不会起作用。
public class Foo {
public static int crunch(String str) {
int y = 0;
int limit = str.length() > 6 ? 6 : str.length();
for (int i = 0; i < limit; ++i) {
y += str.charAt(i) * (limit - i);
}
return y;
}
public static void main(String[] args) {
String[] words = new String[]{
"abcdef", "acdefb", "fedcba", "}}}}}}", "ZZZZZZ", "123", "!"
};
for (int idx = 0; idx < words.length; ++idx) {
System.out.printf("in=%-6s out=%04d\n",
words[idx], crunch(words[idx]));
}
}
}
生成:
in=abcdef out=2072
in=acdefb out=2082
in=fedcba out=2107
in=}}}}}} out=2625
in=ZZZZZZ out=1890
in= 123 out=0298
in= ! out=0033
答案 4 :(得分:0)
您必须对字符可以具有的值范围以及何时是可接受的编码字符进行假设。有很多方法可以做到这一点。您可以将字符串打包为1,2,3,4或5个字符,具体取决于您的假设。
一个可以给你4个字符的简单例子是假设最后三个字母是一个数字。
public static String pack(String text) {
return text.substring(0, 3) + (char) Integer.parseInt(text.substring(3));
}
public static String unpack(String text) {
return text.substring(0, 3) + ("" + (1000 + text.charAt(3))).substring(1);
}
public static void main(String[] args) throws IOException {
String text = "ABC123";
String packed = pack(text);
System.out.println("packed length= " + packed.length());
String unpacked = unpack(packed);
System.out.println("unpacked= '" + unpacked + '\'');
}
打印
packed length= 4
unpacked= 'ABC123'