Tworzenie $Key w DC

0

Mój problem jest następujący. Po nawiązaniu połączenia (socket) hub DC wysyła do klienta DC komende $Lock jakiś_ciąg_znaków. Zadaniem Klienta jest odpowiedzenie komendą $Key inny_ciąg_znaków z tą różnicą ze "inny_ciąg_znaków" powstaje na podstawie algorytmu 'zastosowanego' na "jakiś_ciąg_znaków". Niestety nie mam pojęcia jak to zaimplementować w C++ Builder 5. Chciałem nadmienić, iż nie jestem zaawansowanym programistą. Aktualnie udało mi się wydzielić do AnsiString jakiś_ciąg_znaków, ale jego trzeba przerobić i wysłać $Key'a jako string (czyli tablice char - tak mi sie wydaje). Osobom, które zdecydowałyby się mi pomóc załączam odpowienią część specyfikacji DC. Byłbym wdzięczny np. za gotowy kod i ew. wskazówki dlaczego tak a nie inaczej. Ja wiem ze w specyfikacji jest jak byk napisane jak to zrobić...ale to nie jest C++ i nie wiem jak to przerobić.
P.S. NA PRARAMETR PK CHYBA NIE TRZEBA ZWRACAC UWAGI.
P.S.2 I jak wyglada sprawa z tymi /%DCN124%/ czy da sie takie cos przeslac jako jeden char?

[code]
Appendix A: Converting a Lock into a Key
As part of the initial negotiation between the client and hub, the hub sends a $Lock <lock> Pk=<pk> command and the client must respond with a $Key <key> command. Until the DCN encoding, which we'll discuss last, the <key> has exactly as many characters as the <lock>.

Except for the first, each key character is computed from the corresponding lock character and the one before it. If the first character has index 0 and the lock has a length of len then:

for (i = 1; i < len; i++)
key[i] = lock[i] xor lock[i-1];
The first key character is calculated from the first lock character and the last two lock characters:

key[0] = lock[0] xor lock[len-1] xor lock[len-2] xor 5
Next, every character in the key must be nibble-swapped:

for (i = 0; i < len; i++)
key[i] = ((key[i]<<4) & 240) | ((key[i]>>4) & 15)
Finally, the characters with the decimal ASCII values of 0, 5, 36, 96, 124, and 126 cannot be sent to the server. Each character with this value must be substituted with the string /%DCN000%/, /%DCN005%/, /%DCN036%/, /%DCN096%/, /%DCN124%/, or /%DCN126%/, respectively. The resulting string is the key to be sent to the server.

If your programming language of choice doesn't have xor or shift operations on characters, convert them to integers. If it doesn't have a bit shift at all, then x << y = x*(2y) and x >> y = x/(2y) for all integers x and y (** is the exponent operation or "to the power of"). Be sure to use unsigned values everywhere and do not do sign extension. Shift operations always lose the high or low bit (they are not roll operations!). The & (and) and | (or) operations are all logical, not boolean (eg. 6 & 13 = 4, not 1).

When the hub connects to the hublist, it must undergo a similar Lock/Key negotiation. The <key> calculation is the same, but the special number 5 in the second step is replaced with the following value computed from the hub's port, localport:

((localport>>8) + (localport & 255)) & 255
NOTE: The NMDC hub does not follow this Lock/Key negotiation! As far as I can tell it uses a completely random first char instead of bit shifting the port right 8 bytes.
[/code]

0

Musisz sobie zadeklarować key i lock jako zwykly ciag znaków (char*), żadne ansi. i taki tekst obrabiać... Resztę po prostu przepisujesz, z jedną różnicą, że zamiast 'xor' piszesz '^'.

0

Zrobilem tak jak mowiles i mój kod wygląda następująco:

{
   AnsiString s;
   Memo1->Lines->Add("Reading...");
   s = Socket->ReceiveText();
   Memo1->Lines->Add(s);
   Memo1->Lines->Add("Utworzylem lancuch o tresci: " + s);
   int spacja = s.AnsiPos(" ");
   AnsiString cmd;
   cmd = s.SubString(1, spacja-1);
   if (cmd == "$Lock")
   {
      //Wydzielenie lancucha danych
      int dl = s.Length();
      AnsiString dane;
      dane = s.SubString(spacja+1,dl-spacja+1);
      Memo1->Lines->Add(dane);
      //Wydzielenie samego locka
      int pk = dane.AnsiPos(" Pk");
      AnsiString locka = dane.SubString(1,pk-1);
      Memo1->Lines->Add(locka);
      //Konwersja locka na keya
      int len = locka.Length();
      char* lock = locka.c_str();
      char* key;
      for (int i=1; i<len; i++)
      {
         key[i] = lock[i] ^ lock[i-1];
      }
      key[0] = lock[0] ^= lock[len -1] ^ lock[len -2] ^ 5;
      for (int i=0; i<len; i++)
         key[i] = ((key[i]<<4)&240) | ((key[i]>>4) & 15);
      AnsiString keya = key;
      Memo1->Lines->Add(keya);
   }
}

Kompiluje się bez problemu. Jednak problemem jest to że po uruchomieniu tego kodu to niezależnie od locka mam zawsze tego samego Key'a o tresci ÁŃŔ° A ѱ±ŔŔ0g .Zawsze jest taki sam. Mam namiary jak ma wygladać m/w dobry Key bo przechwycilem snifferem (ale wiadomo rozny sie w zal. od Locka przeslanego przez Hub):
$Key eŃŔ.°...A ѱ±ŔŔ0g/%DCN000%/ćĂ.ˇÂsŃqÓ‚a!‚P±Ń/%DCN000%/.°.Ó±b/%DCN096%/cÁ±.5/%DCN000%/pJUłd‡/%DCN126%/Ú.âłě^ěŻa|

Ten począteczek jakby podobny...ale gdzie reszta?
...No i czy po zamianie liczb np. 5 na /%DCN005%/ ten caly ciag to jest jeden char?
Prosze o pomoc...

1 użytkowników online, w tym zalogowanych: 0, gości: 1