Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java字符串中对二进制数据进行bencoding_Java_Python_Encoding - Fatal编程技术网

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

在Java字符串中对二进制数据进行bencoding,java,python,encoding,Java,Python,Encoding,我正在使用bencoding,我希望将bencoded字符串保留为Java字符串,但它们包含二进制数据,因此盲目地将其转换为字符串将损坏数据。我试图实现的是一个转换函数,它将ASCII字节保持为ASCII,并以可逆的方式对非ASCII字符进行编码 我已经找到了一些我试图用Python实现的示例,但我对Python的了解还不够深入。这正是我想要做的:torrent的ASCII部分保持为ASCII,但sha1哈希打印为“\xd8r\xe7”。虽然我的Python知识非常有限,但他似乎没有对字符串做任

我正在使用bencoding,我希望将bencoded字符串保留为Java字符串,但它们包含二进制数据,因此盲目地将其转换为字符串将损坏数据。我试图实现的是一个转换函数,它将ASCII字节保持为ASCII,并以可逆的方式对非ASCII字符进行编码

我已经找到了一些我试图用Python实现的示例,但我对Python的了解还不够深入。这正是我想要做的:torrent的ASCII部分保持为ASCII,但sha1哈希打印为“\xd8r\xe7”。虽然我的Python知识非常有限,但他似乎没有对字符串做任何特殊的处理;这是由Python解释器处理的吗?我可以用Java实现同样的功能吗

我已经使用了一些编码,比如Base64或使用Integer.toHexString,但最终得到了无法读取的ASCII字符串


我还找到了一个可以打印除sha1散列以外的所有内容的字符串。

Bencoded字符串是字节字符串。您可以尝试使用
字符串(byte[]bytes,Charset Charset)
将字节字符串解码为Java中的unicode码点。使用某些编码(如ISO-8859-1)进行解码将始终成功,因为任何字节都直接映射到一个码点。有了许多这样的编码(包括ISO-8859-1),这个过程也是可逆的。

如果,格式似乎足够简单。直接解析字节数据:

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");
  }

是的,这就是我现在正在做的事情,但是本编码字符串包含二进制数据,而不仅仅是文本,至少在torrents中是这样。构建常规字符串将损坏sha1的。呃,它不应该。。。只要代码点覆盖整个0-255字节范围,过程中就不会发生任何变化。认为ISO-8859-1对0-255范围内的字节进行1:1映射是一个常见的错误。ISO-8859-1在128-159范围内未定义,因此尝试将该范围内的字节转换为字符将导致“?”作为未知字符的最佳表示形式。@jarnbjo,ISO 8859-1是一种不定义某些代码点的编码,ISO-8859-1是这样做的。维基百科的文章有更多的细节。@Hamza Yerlikaya,不会的。如果使用ISO-8859-1再次编码字符串,则生成的字节相同。或者在代码中:Arrays.equals(字节,新字符串(字节,字符集.forName(“ISO-8859-1”))。getBytes(“ISO-8859-1”)==true(对于任何字节[]字节)。
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"));
  }
}