将Torrent info_hash从bencoded转换为URLEncoded数据

Oti*_*ium 6 bittorrent http objective-c ios afnetworking

我在objective-c中创建了torrent scraper,我正在使用AFNetworking来处理HTTP请求.我需要发送跟踪器请求的元信息部分的sha1哈希值.我已成功创建哈希并验证它是否正确.我不能将哈希值放在NSString中,因为它不对二进制数据进行编码,因此我将它放在NSData对象中,然后在要发送的参数中.这就是我现在所拥有的,但我总是得到一个错误,我会假设它是使用我用来发送哈希的方法.我也尝试过编码哈希的url然后把它放在NSString中但没有用

 NSMutableDictionary *parameters = [NSMutableDictionary dictionary];

 unsigned char infoHash[20];
 [self.tracker generateTorrentInfoHash:infoHash];

 const char peer_id[20] = "randomstringfornow";

[parameters setObject:[NSData dataWithBytes:&infoHash length:20] forKey:@"info_hash"];    
[parameters setObject:[NSData dataWithBytes:&peer_id length:20] forKey:@"peer_id"];
[parameters setObject:@(8080) forKey:@"port"];
[parameters setObject:@(0) forKey:@"uploaded"];
[parameters setObject:@(self.tracker.metaInfo.totalFileSize) forKey:@"left"];
[parameters setObject:@(0) forKey:@"downloaded"];
[parameters setObject:@(0) forKey:@"compact"];
[parameters setObject:@"stopped" forKey:@"event"];


[self getPath:@"" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"%@",operation.responseString);


   } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"%@",operation.responseString);
}];
Run Code Online (Sandbox Code Playgroud)

有没有人知道AFNetworking是否有可能这样做,或者我希望错过一些简单的事情.

Ada*_*m B 5

好吧,我不是在种子方面的专家,但我认为你遇到的挑战是,B编码你从拉动编码数据表示SHA1哈希数据的20个原始字节。

您不能在 HTTP 请求的 GET 部分发送这样的原始数据,因此您需要对其进行编码。根据规范,对原始数据进行urlencoding似乎是这样做的官方方法。(例如,其他选项是将其转换为人类可读的十六进制字符串)。

从这个替代 Bittorrent 规范

跟踪器是响应 HTTP GET 请求的 HTTP/HTTPS 服务。这些请求包括来自客户端的指标,这些指标可帮助跟踪器保留有关 torrent 的总体统计信息。响应包括帮助客户端参与 torrent 的对等列表。基本 URL 由元信息 (.torrent) 文件中定义的“公告 URL”组成。然后使用标准的 CGI 方法将参数添加到此 URL(即,在announce URL 之后的“?”,然后是由“&”分隔的“param=value”序列)。

请注意,必须正确转义 URL 中的所有二进制数据(尤其是 info_hash 和 peer_id)。这意味着任何不在集合 0-9、az、AZ、'.'、'-'、'_' 和 '~' 中的字节都必须使用“%nn”格式进行编码,其中 nn 是字节。(有关详细信息,请参阅 RFC1738。)

对于 20 字节的哈希 \x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a

正确的编码形式是 %124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A

从原始的 20 个字符 C 数组开始,您需要获取URLEncoded NSString

不幸的是,特别是对于这种类型的数据,stringByAddingPercentEscapesUsingEncoding在循环中使用的简单方法将不起作用,因为它最终没有安全编码作为 GET 参数发送。

借助一些 SO 帮助(如何对字符串进行 URL 编码),这里有一些代码,您可以将其塑造成最终产品,但符合规范文档以获得正确输出:

const char source[20] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9a};

NSMutableString *output = [NSMutableString string];

NSLog(@"Raw Data: %@", [NSData dataWithBytes:source length:20]);

int sourceLen = sizeof(source);

for (int i = 0; i < sourceLen; ++i) {
    const unsigned char thisChar = source[i];
    if (thisChar == ' '){
        [output appendString:@"+"];
    } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || 
               (thisChar >= 'a' && thisChar <= 'z') ||
               (thisChar >= 'A' && thisChar <= 'Z') ||
               (thisChar >= '0' && thisChar <= '9')) {
        [output appendFormat:@"%c", thisChar];
    } else {
        [output appendFormat:@"%%%02X", thisChar];
    }
}

NSLog(@"Encoded:  %@", output);
Run Code Online (Sandbox Code Playgroud)

输出是:

Raw Data: <12345678 9abcdef1 23456789 abcdef12 3456789a>
Encoded:  %124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A
Run Code Online (Sandbox Code Playgroud)

祝你好运!