Objective-C iOS从Torrent文件生成Info_Hash

时间:2015-02-28 14:56:53

标签: ios objective-c torrent

我正在尝试从我下载的torrent文件中生成一个info_hash。我使用uTorrent创建了Torrent文件,并使用PeerTracker作为我的跟踪软件。

我正在使用此处找到的代码的更新版本:
https://code.google.com/p/rouge-server/source/browse/trunk/driver/objective-c/RougeDriver/BEncoding.m?r=88

{
    announce = "http://sub.url.com:8080/announce.php";
    "created by" = "uTorrent/1870";
    "creation date" = 1425134140;
    encoding = "UTF-8";
    info =     {
        length = 4;
        name = "test.txt";
        "piece length" = 16384;
        pieces = "\U00a9J\U00e8\U00c2\U00c3\U00b1\U00f5\U00b6L\bs\U201d\U00eb\U00c8\U00e1\U00f2/\U00aa\U201d";
    };
}

以下是我正在使用的确切编码方法:

+ (void)encode:(id)object toString:(NSMutableString *)string
{
    if([object isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *dictionary = (NSDictionary *)object;
        [string appendString:@"d"];

        for(id key in [dictionary allKeys])
        {
            [self encode:key toString:string];
            [self encode:[dictionary objectForKey:key] toString:string];
        }

        [string appendString:@"e"];
    }
    else if([object isKindOfClass:[NSString class]])
    {
        NSString *stringObject = (NSString *)object;
        NSString *format = @"%lu:%@";

        [string appendFormat:format, [string length], stringObject];
    }
    else if([object isKindOfClass:[NSArray class]])
    {
        NSArray *array = (NSArray *)object;
        [string appendString:@"l"];

        for(id item in array)
        {
            [self encode:item toString:string];
        }

        [string appendString:@"e"];
    }
    else if([object isKindOfClass:[NSNumber class]])
    {
        NSNumber *number = (NSNumber *)object;
        NSString *format = @"i%de";

        [string appendFormat:format, [number intValue]];
    }
}

这是我第一次使用Torrent和bencoding。我知道我只应该对主词典中包含的“信息”字典进行编码。

有谁知道我在哪里可能会出错?

2 个答案:

答案 0 :(得分:1)

实际的pieces内容是数据:

0xa9, 0x4a, 0x8f, 0xe5, 0xcc, 0xb1, 0x9b, 0xa6, 0x1c, 0x4c, 0x08, 0x73, 0xd3, 0x91, 0xe9, 0x87, 0x98, 0x2f, 0xbb, 0xd3

正如@Encombe所说,这是SHA1哈希。

来自维基百科:

  

规范不涉及ASCII集外的字符编码;为了缓解这种情况,一些BitTorrent应用程序以各种非标准方式明确地传达编码(最常见的是UTF-8)。

pieces是十六进制数据,而不是UTF-8。

答案 1 :(得分:1)

我终于找到了解决这个问题的方法。众所周知,这是一个编码问题。

我按照这个SO的说明: Calculating the info-hash of a torrent file

然而,我做了一个小小的调整:

+ (NSDictionary *)decodeDictionary:(HTData *)data
{
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

    [data getNextCharacter];

    while([data showNextCharacter] != 'e')
    {
        NSString *key = [self decodeString:data];

        id object;

        if([key isEqualToString:@"info"])
        {
            NSInteger startIndex = [data getCurrentIndex];
            NSInteger endIndex;
            object = [self decodeNextObject:data];

            endIndex = [data getCurrentIndex];

            NSMutableData *charData = [[NSMutableData alloc] init];

            for(NSInteger i = startIndex; i < endIndex; i++)
            {
                char c = [data charAtIndex:i];
                [charData appendBytes:&c length:1];
            }

            NSData *hashedInfo = [charData SHA1];

            [dictionary setObject:hashedInfo forKey:@"info_hash"];
        }
        else
        {
            object = [self decodeNextObject:data];
        }

        [dictionary setObject:object forKey:key];
    }

    [data getNextCharacter];

    return dictionary;
 }

我现在正在计算字典解码器中的哈希值。我还与个人chars合作,并将其直接附加到NSMutableData个对象。这样可以避免我遇到的编码问题,并生成正确的哈希值。

不是最优雅的解决方案,但我很高兴它有效。