Nano Hash - криптовалюты, майнинг, программирование

Как я могу расшифровать значение пиров в ответе трекера (Bittorent)

Я пытаюсь реализовать протокол BitTorent самостоятельно, и у меня возникла проблема с декодированием значения «Peers» в ответе трекера с использованием С++.

В соответствии с документацией по протоколу BitTorent:

peers: (двоичная модель) Вместо использования модели словаря, описанной выше, значением peers может быть строка, состоящая из кратных 6 байтов. Первые 4 байта — это IP-адрес, а последние 2 байта — номер порта. Все в сетевой записи (с обратным порядком байтов).

Как я могу декодировать этот IP-адрес и номер порта с помощью С++?

У меня есть этот код, но он неверен:

void DecodePeers(OrderedMap<std::string, int> &map, const char * buffer, int i)
{
    int counter = 0;



    while (*(buffer + counter) != NULL)
    {

        //std::vector<TByte> portNum;
        short port;

        for (int i = counter; i < counter + 4; i++)
        {
            //*(peerIp + i - counter) = *(buffer + i);
        }

        counter += 4;

        //*(peerIp + 4) = '\0';
        char twobytes[2];

        twobytes[0] = *(buffer + counter + 0);
        twobytes[1] = *(buffer + counter + 1);

        unsigned int x;
        std::stringstream ss;
        ss << std::hex << twobytes[0];
        ss >> x;
        // output it as a signed type
        std::cout << static_cast<int>(x) << std::endl;

        port = ((twobytes[1] << 8) | twobytes[0]);
        //port = (short) twobytes;
        counter += 2;

        //std::string str(portNum.begin(), portNum.end());

        std::cout << std::endl;

        std::cout << port << std::endl ;

        char  * bbuffer = new char[100];

        for (int i = 0; i < 1; i++) {
            //unsigned int inte = (unsigned int)str;(
            //_itoa_s((int) *str.c_str(), bbuffer, 100, 10);
            //sprintf_s(bbuffer, 50, (const char *) "%d", str.c_str());
        }

        std::cout << std::endl;
        //int port = atoi(portNum);
        //map.Insert(str, port);
    }

}

Кто-нибудь знает, как я могу перевести эти числа в число - читаемый ответ?

Example of peers value: P^L♠*j.t╤u→πe199711

  • Знаете ли вы, какой ip должен получиться из этого числа? Я получаю эти 80.94.76.226 29742 42.106.46.116 14641 13.11.2015
  • Может быть, это правильно. Как вы этого достигли? 14.11.2015
  • Вы не отвечали, поэтому я написал как ответ, код уже здесь 15.11.2015

Ответы:


1

Я пытался использовать этот код в вашем буфере для декодирования одноранговых узлов протокола BitTorrent.

#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    char *buf = "P^L♠*j.t╤u→πe199711";
    int chunks = strlen(buf) / 6 ;
    int offset =  0;
    unsigned char *ip;
    unsigned short *port;
    int recsDone = 0;
    while (recsDone++ <= chunks){
        ip   = (unsigned char *) buf+offset;
        port = (unsigned short *) buf+offset+4;
        printf("%s - %d\n",inet_ntoa(*(in_addr*)ip),ntohs(*port));
        offset+=6;
    }
}

и я получаю это как вывод:

80.94.76.226 - 11892 42.106.46.116 - 12601

Пожалуйста, дайте нам знать, если это работает.

13.11.2015
  • Большое спасибо! Код работает нормально, но обратите внимание, что вы указали sizeof(buf)/6, sizeof возвращает размер переменной, а поскольку buf является указателем, он всегда будет возвращать 4, вместо sizeof я поставил strlen(buf) / 6, и это сработало! Большое спасибо! :) 15.11.2015
  • Пожалуйста, и вы правы насчет длины, я ее исправил. 16.11.2015

  • 2

    Я не работал с этим протоколом, и показанный код немного сбивает с толку. Я не знаю, что такое peerIp, например. Но на основании описания поля в peer_id, https://wiki.theory.org/BitTorrentSpecification#peer_id, я бы предложил:

    #include <arpa/inet.h>
    #include <stdint.h>
    #include <stdio.h>
    
    uint32_t *peerIPAux;
    
    struct sockaddr_in peer_data;
    char str[INET_ADDRSTRLEN];
    uint16_t *peer_port_ptr;
    uint16_t peer_port;
    
    //Here we need to test if IPv4 address, represented in an integer value is 
    //actually in network notation or not. First assume what documentation says 
    //is true (it is in network notation)
    
    //INSIDE THE WHILE LOOP
    
    peerIPAux = (uint32_t *)(buffer + counter);
    peer_data.sin_addr.s_addr = ntohl(*peerIPAux); //If this doesn't work try without ntohl
    
    //http://linux.die.net/man/3/inet_ntop
    
    inet_ntop(AF_INET, &(peer_data.sin_addr), str, INET_ADDRSTRLEN); //check error code here
    
    printf("%s\n", str); // or std::cout << str << std::endl;
    
    counter += 4;
    peer_port_ptr = (uint16_t *) (buffer + counter);
    
    peer_port = ntohs(*peer_port_ptr);
    
    printf("PORT: %d", peer_port); // in C
    ....
    
    13.11.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..