Well, I'm not an expert in torrents, but I think the problem you are facing is that the encoded representation of the data that is issued encodes the SHA1 hash as 20 raw bytes of data.
You cannot send raw data in the GET part of the HTTP request, so you will need to encode it. Based on the specifications, it seems that urlencoding the source data is the official way to do this. (Other options might convert it to a human-readable hexadecimal string, for example).
From this alternative specification of Bittorrent :
A tracker is an HTTP / HTTPS service that responds to HTTP GET requests. Requests include customer metrics that help you track general torrent statistics. The answer includes a peer list that helps the client participate in the torrent. The primary URL consists of a "URL declaration" as defined in the metainfo (.torrent) file. Parameters are then added to this URL using standard CGI methods (ie "?" After the announcement URL and then the sequences "param = value" separated by "&").
Note that all binary data in the URL (especially info_hash and peer_id) must be properly escaped. This means that any byte not in the set 0-9, az, AZ, '.', '-', '_' and '~' must be encoded using the format "% nn", where nn is the hexadecimal value of the bytes . (See RFC1738 for more details.)
For a 20-byte hash \x12\x34\x56\x78\x9a\xbc\xde\xf1\x23\x45\x67\x89\xab\xcd\xef\x12\x34\x56\x78\x9a
Correct coded form %124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A
Starting from your original 20 char C array, you need to go to URLEncoded NSString .
Unfortunately, especially with this data type, a simple method - using stringByAddingPercentEscapesUsingEncoding in a loop - will not work, because in the end it will not receive a secure encoding for sending as a GET parameter.
With a bit of SO help ( How to encode a URL string ), here is some code that you can embed in the final product, but meets the doc specification for the correct output:
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);
Exit:
Raw Data: <12345678 9abcdef1 23456789 abcdef12 3456789a> Encoded: %124Vx%9A%BC%DE%F1%23Eg%89%AB%CD%EF%124Vx%9A
Good luck