2015-02-28 1 views
1

Je suis en train d'essayer de générer un info_hash à partir d'un fichier torrent que j'ai téléchargé. J'ai créé le fichier Torrent en utilisant uTorrent et en utilisant PeerTracker comme logiciel de suivi.Objective-C iOS Génération d'Info_Hash à partir du fichier Torrent

J'utilise une version mise à jour du code trouvé ici:
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"; 
    }; 
} 

est inférieure à la méthode de codage exacte J'utilise:

+ (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]]; 
    } 
} 

C'est la première fois travailler avec Torrents et bencoding. Je sais que je suis seulement supposé Encoder le dictionnaire "info" contenu dans le dictionnaire principal.

Est-ce que quelqu'un sait où je pourrais me tromper ici?

+0

'pieces' ne semble pas être UTF-8 mais un mixage incluant UTF-16:" \ U00a9 "semble être le codage de caractères UTF-16 pour" © ". – zaph

+0

De quoi aurais-je besoin pour supprimer cela? Est-ce dans le décodage? ou encodage? –

+1

Je n'ai pas dit que vous aviez besoin de supprimer quoi que ce soit. Dans la question: "encoding =" UTF-8 "mais beaucoup de caractères semblent être UTF-16 Il semble y avoir une discordance – zaph

Répondre

1

J'ai finalement trouvé la solution à ce problème. Comme tout le monde le soupçonnait, c'était un problème d'encodage.

J'ai suivi les instructions de ce SO: Calculating the info-hash of a torrent file

Cependant, je fait un petit tweak:

+ (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; 
} 

Je calculer maintenant le hachage dans le décodeur de dictionnaire. Je travaille également avec l'individu chars et les ajoute directement à un objet NSMutableData. Cela évite les problèmes d'encodage que j'avais et génère le hachage correct.

Pas la solution la plus élégante mais je suis content que ça marche.

1

Le contenu pieces réel sont des données:

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

Comme l'indique ce @Encombe est le hachage SHA1.

de Wikipédia:

La spécification ne traite pas avec le codage de caractères en dehors du jeu ASCII; Pour atténuer cela, certaines applications BitTorrent communiquent explicitement l'encodage (le plus souvent UTF-8) de diverses manières non standard.

Et pieces est des données hexadécimales, pas UTF-8.

+0

Mais ne suis-je pas destiné à encoder l'ensemble du dictionnaire "info" pour générer le info_hash que je peux annoncer? Ou y at-il quelque chose de spécial que je dois faire avec ces données avant d'encoder le dictionnaire d'information? –

+0

L'article wikipedia est un peu désuet. [La spécification du protocole BitTorrent - BEP3] (http://bittorrent.org/beps/bep_0003.html) a été mise à jour et indique désormais explicitement UTF-8. – Encombe

+0

Peut-être que cette réponse peut aider: http://stackoverflow.com/questions/19749085/calculating-the-info-hash-of-a-torrent-file/19800109#19800109 – Encombe