【问题标题】: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 511 251 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é”中),它会失败。

            但如果你知道你永远不会遇到这种情况,那么上述方法可能对你有用。

            【讨论】:

              猜你喜欢
              • 2015-03-29
              • 1970-01-01
              • 1970-01-01
              • 2012-07-04
              • 1970-01-01
              • 1970-01-01
              • 2018-11-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多