【问题标题】:Convert set of ascii characters back to string将一组 ascii 字符转换回字符串
【发布时间】:2014-01-02 04:12:23
【问题描述】:
我目前正在将字符串转换为 ascii 字符的情况:
String str = "are"; // or anything else
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray())
sb.append((int)c);
BigInteger mInt = new BigInteger(sb.toString());
System.out.println(mInt);
输出(在这种情况下)是97114101 我正在努力寻找一种方法来扭转这种情况,将 ascii 字符的字符串转换回字符串,例如“是”
【问题讨论】:
标签:
java
string
type-conversion
ascii
long-integer
【解决方案1】:
简单的答案是您不能丢失数据。你无法知道每个字符有多少个数字。
数字之间需要某种分隔符。
【解决方案2】:
答案是一个很大的否,你无法用你现有的方法找回它。
相反,您可以使用整数数组(如果可能)。如果你解释你为什么实际上这样做,你可能会得到最好的解决方案。
【解决方案3】:
如果您在字符串中使用的所有字符都是两位数的 ASCIS,这可能是可行的。例如:“ARE”会给出“658269”,您会知道一次处理两个数字来反转它。这里的问题是你现在不知道它是两位数还是三位数的 ASCI 代码......
但是,如果是纯字符串值 [a-zA-Z],您可以查看两位数是否在 [65-90] 或 [97-99] 范围内,否则取三位数,应该是在 [100-122] 范围内
但不言而喻,有更好的方法来做到这一点。
【解决方案4】:
你不能用十进制数来做,因为它们的表示中的位数会发生变化。因此,您将无法区分序列112 5、11 25 和1 125。
但是,您可以强制每个字符占用三个数字。在这种情况下,您可以通过反复除以 1000 并取余数来恢复该数字:
for (char c : str.toCharArray()) {
String numStr = String.valueOf((int)c);
while (numStr.length() != 3) numStr = "0"+numStr;
sb.append(numStr);
}
如果您只使用 UNICODE 代码点的 ASCII 部分,这有点浪费,因为您需要的值大部分是两位数。如果你切换到十六进制,所有的 ASCII 码位都适合两位数:
for (char c : str.toCharArray()) {
String numStr = Integer.toString(c, 16);
if (numStr.length() == 1) numStr = "0"+numStr;
sb.append(numStr);
}
BigInteger mInt = new BigInteger(sb.toString(), 16);
现在您可以使用除以 256 而不是 1000。
【解决方案5】:
正如其他人所指出的,这一般来说是不可行的。但是,正如其他人也认为的那样,如果您做出某些限制性假设,这是可行的。除了已经介绍的那些之外,另一个假设可能是您要转换的字符串都是英文单词。
那么你就会知道每个字符在整数中占据 2 位或 3 位数字。下面的代码举例说明了一个函数的使用,它检查 2 位数字是否正常,或者您是否必须考虑 3 位数字:
public String convertBack(BigInteger bigInteger) {
StringBuilder buffer = new StringBuilder();
String digitString = bigInteger.toString();
for (int to, from = 0; from + 2 <= digitString.length(); from = to) {
// minimally extract two digits at a time
to = from + 2;
char c = (char) Integer.parseInt(digitString.substring(from, to));
// if two digits are not enough, try 3
if (!isLegalCharacter(c) && to + 1 <= digitString.length()) {
to++;
c = (char) Integer.parseInt(digitString.substring(from, to));
}
if (isLegalCharacter(c)) {
buffer.append(c);
} else {
// error, can't convert
break;
}
}
return buffer.toString();
}
private boolean isLegalCharacter(char c) {
return c == '\'' || Character.isLetter(c);
}
这种特殊的isLegalCharacter 方法不是很强大,但是您可以根据需要对其进行调整。例如,对于元音变音字符(例如,在单词“naïveté”中),它会失败。
但如果你知道你永远不会遇到这种情况,那么上述方法可能对你有用。