【问题标题】:Convert byte array to escaped string将字节数组转换为转义字符串
【发布时间】:2019-09-11 18:40:20
【问题描述】:

我需要一些帮助,将 java 字节数组转换为 7 位 ASCII 字符串。但是,我得到 8 位序列,需要将任何不可读的字符转义到它的转义序列。是否有一个简单的解决方案或者我需要自己构建?

看到 7 位 ASCII 中可读字符的范围是连续的,我现在正在考虑以下内容:

for( int i = 0; i < buffer.length; i++ ) {
   int codePoint = ( (int) buffer[ i ] ) & 255;
   if( 0x20 <= codePoint && codePoint <= 0x7e ) {
      res = res + String( (char) codePoint );
   } else {
     String c = Integer.toHexString( codePoint );
     if( c.length() < 2 ) {
       c = "0" + c;
     }
     res = res + "\\0x" + c;
   }
}

但是,对于如此简单的转换来说,这似乎是一项非常艰巨的工作。有没有更好的办法?

另外,我可能需要对已从字节数组转换为字符串的数据执行相同的操作。在这种情况下有更简单的解决方案吗?

【问题讨论】:

  • 这正是 base64 的设计目的。对于字符串,使用getBytes(Charset) 方法(你必须决定你希望输出的字符集编码)。
  • 0x20 &gt;= codePoint &amp;&amp; codePoint &gt;= 0x7e 始终为假。我想你的意思是&lt;=
  • @Jim:是的,这是一个错字。固定。
  • 不,Base64 不是我在这里需要的。我不需要任何类型的完整 8 位编码,而是人类可读的编码。原因是,我想记录字符串,它的前面可能还包含一些额外的标题,我想尽可能简单地打印出来。实际上,仅对标头进行解码并以解码的方式打印它可能会更简单。

标签: java ascii


【解决方案1】:
  public static String escape(byte[] data) {
    StringBuilder cbuf = new StringBuilder();
    for (byte b : data) {
      if (b >= 0x20 && b <= 0x7e) {
        cbuf.append((char) b);
      } else {
        cbuf.append(String.format("\\0x%02x", b & 0xFF));
      }
    }
    return cbuf.toString();
  }

您可以使用format 方法来减少措辞。

请注意,此方法仅是安全的,因为 ASCII 范围与 Java 字符串使用的 UTF-16 编码的下限匹配。

【讨论】:

  • 比我做的方式更干净一些,但对于这样一个简单的任务来说似乎仍然需要做很多工作。被接受是因为我以一种完全不相关的方式解决了这个问题,使整个程序更加简洁。
【解决方案2】:

如果它不适合 base64,那么第二个标准是 java.net.URLEncoder

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2021-11-11
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多