在Java字符串中对二进制数据进行bencoding
我正在使用bencoding,我希望将bencoded字符串保留为Java字符串,但它们包含二进制数据,因此盲目地将其转换为字符串将损坏数据。我试图实现的是一个转换函数,它将ASCII字节保持为ASCII,并以可逆的方式对非ASCII字符进行编码 我已经找到了一些我试图用Python实现的示例,但我对Python的了解还不够深入。这正是我想要做的:torrent的ASCII部分保持为ASCII,但sha1哈希打印为“\xd8r\xe7”。虽然我的Python知识非常有限,但他似乎没有对字符串做任何特殊的处理;这是由Python解释器处理的吗?我可以用Java实现同样的功能吗 我已经使用了一些编码,比如Base64或使用Integer.toHexString,但最终得到了无法读取的ASCII字符串在Java字符串中对二进制数据进行bencoding,java,python,encoding,Java,Python,Encoding,我正在使用bencoding,我希望将bencoded字符串保留为Java字符串,但它们包含二进制数据,因此盲目地将其转换为字符串将损坏数据。我试图实现的是一个转换函数,它将ASCII字节保持为ASCII,并以可逆的方式对非ASCII字符进行编码 我已经找到了一些我试图用Python实现的示例,但我对Python的了解还不够深入。这正是我想要做的:torrent的ASCII部分保持为ASCII,但sha1哈希打印为“\xd8r\xe7”。虽然我的Python知识非常有限,但他似乎没有对字符串做任
我还找到了一个可以打印除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"));
}
}