gpt4 book ai didi

java - 无法创建 torrent 的信息哈希

转载 作者:行者123 更新时间:2023-12-02 09:11:38 26 4
gpt4 key购买 nike

我无法找到如何为 torrent 文件生成相应信息哈希的问题。这是我到目前为止的代码:

InputStream input = null;
try {
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
input = new FileInputStream(file);
StringBuilder builder = new StringBuilder();
while (!builder.toString().endsWith("4:info")) {
builder.append((char) input.read()); // It's ASCII anyway.
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
for (int data; (data = input.read()) > -1; output.write(data));
sha1.update(output.toByteArray(), 0, output.size() - 1);
this.infoHash = sha1.digest();
System.out.println(new String(Hex.encodeHex(infoHash)));
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
} finally {
if (input != null) try { input.close(); } catch (IOException ignore) {}
}

下面是我的预期和实际哈希值:

Expected: d4d44272ee5f5bf887a9c85ad09ae957bc55f89d
Actual: 4d753474429d817b80ff9e0c441ca660ec5d2450

可以找到我尝试生成信息哈希的 torrent here (Ubuntu 14.04 Desktop amd64) .

如果我可以提供更多信息,请告诉我,谢谢!

最佳答案

异常包含 4 个有用的信息:类型、消息、跟踪和原因。您已经丢弃了 4 个相关信息中的 3 个。此外,代码是流程的一部分,当发生错误时,通常该流程根本无法完成。然而,在异常(exception)情况下,您的过程仍会继续。停止这样做;你编写的代码只会伤害你。删除尝试和捕获。在方法签名中添加一个 throws 子句。如果不能,默认情况下(如果生成此代码,则更新您的 IDE)是 throw new RuntimeException("Unhandled", e);。这更短,不会破坏任何 4 个有趣的信息位,并结束一个进程。

另外,处理输入流 close 方法的 IOException 的正确方法是:忽略它的观点也是错误的。它不太可能抛出,但如果抛出,您应该假设您没有读取每个字节。由于这是对哈希不匹配的一种解释,因此它是错误的。

最后,使用正确的语言结构:这里有一个 try-with-resources 语句,效果会更好。

您正在使用 output.size() - 1 调用更新;除非你想故意忽略最后一个字节,否则这是一个错误;您正在删除最后读取的字节。

将字节读入构建器,然后按字节将构建器转换为字符串,然后检查最后一个字符,效率极低;对于小至 1MB 的文件来说,这会造成相当大的麻烦。

从原始 FileInputStream 中一次读取一个字节也是低效的,因为每次读取都会导致文件访问(读取 1 个字节与读取整个缓冲区已满一样昂贵,因此,它比需要的速度慢了大约 50000 倍)。

以下是如何使用较新的 API 来完成此操作,并看看这段代码读起来有多好。它在错误条件下也能表现得更好:

byte[] data = Files.readAllBytes(Paths.get(fileName));
var search = "4:info".getBytes(StandardCharsets.US_ASCII);
int searchIdx = -1;
for (int i = 0; searchIdx == -1 && i < data.length - search.length; i++) {
for (int j = 0; j < search.length; j++) {
if (data[i + j] != search[j]) break;
if (j == search.length - 1) searchIdx = i + j;
}
}
if (searchIdx == -1) throw new IOException("Input torrent file does not contain marker");

var sha1 = MessageDigest.getInstance("SHA-1");
sha1.update(data, searchIdx, data.length - searchIdx);
byte[] hash = sha1.digest();
StringBuilder hex = new StringBuilder();
for (byte h : hash) hex.append(String.format("%02x", h));
System.out.println(hex);

关于java - 无法创建 torrent 的信息哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59370657/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com