在Java字符串中进行bencoding二进制数据

2 投票
2 回答
2243 浏览
提问于 2025-04-15 15:36

我在研究bencoding(一个编码方式),想把bencoded字符串保留为Java字符串,但这些字符串里有二进制数据,所以直接转换成字符串会导致数据损坏。我想实现的是一个转换函数,能够把ASCII字符保持为ASCII,同时把非ASCII字符以可逆的方式编码。

我在Python中找到了一些我想实现的例子,但我对Python了解不多,没法深入研究。这个解码器正好实现了我想要的功能:种子的ASCII部分保持为ASCII,但sha1哈希则显示为"\xd8r\xe7"。虽然我对Python的了解非常有限,但看起来他并没有对字符串做什么特别的处理;这是由Python解释器来处理的吗?我能在Java中做到同样的事情吗?

我尝试过一些编码方式,比如Base64或者使用Integer.toHexString,但最后得到的ASCII字符串都很难读。

我还找到一个示例方案,它打印了所有内容,除了sha1哈希。

2 个回答

0

如果维基百科关于Bencode的内容是准确的,那么这个格式看起来挺简单的。直接解析字节数据就可以了:

while (true) {
  in.mark(1);
  int n = in.read();
  if (n < 0) {
    // end of input
    break;
  }
  in.reset();
  // take advantage of some UTF-16 values == ASCII values
  if (n == 'd') {
    // parse dictionary
  } else if (n == 'i') {
    // parse int
  } else if (n >= '0' && n <= '9') {
    // parse binary string
  } else if (n == 'l') {
    // parse list
  } else {
    throw new IOException("Invalid input");
  }

把二进制字符串存储在一种类型中,只有在你明确要求的时候,它才会转换成ASCII格式,比如在这个toString调用中:

public class ByteString {
  private final byte[] data;

  public ByteString(byte[] data) { this.data = data.clone(); }
  public byte[] getData() { return data.clone(); }

  @Override public String toString() {
    return new String(data, Charset.forName("US-ASCII"));
  }
}
2

B编码字符串是字节字符串。你可以在Java中尝试用 String(byte[] bytes, Charset charset) 将字节字符串解码成Unicode字符。使用某些编码方式,比如ISO-8859-1,解码总是能成功,因为每个字节都能直接对应一个字符。在很多这种编码方式中(包括ISO-8859-1),这个过程也是可以反向操作的。

撰写回答