|
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
|
![]()
Сообщение
#1
|
|
![]() Освоившийся участник ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз ![]() |
Итак, по порядку. Известно что хаблисты используют схему $Lock-$Key. Основная проблема заключаеться в том, что этот алгоритм чуть-чуть отличается от обычного. Если быть точным, ровно на первый байт.
В интернете видел информацию, что большинство хаблистов благополучно игнорируют правильность этого кода и есть там один, особо задиристый. Однако, чем черт не шутит. Поэтому наваял свою реализацию на PHP. Но, буду последователен. Исходником послужил код из исходников PtokaX хаба: Код uint16_t lport = (uint16_t)ntohs(addr.sin_port); char cMagic = (char) ((lport&0xFF)+((lport>>8)&0xFF)); // strip the Lock data char *temp; if((temp = strchr(sBuffer+6, ' ')) != NULL) { temp[0] = '\0'; } // Compute the key memcpy(sMsg, "$Key ", 5); sMsg[5] = '\0'; size_t iLen = temp-sBuffer; char v; // first make the crypting stuff for(size_t i = 6; i < iLen; i++) { if(i == 6) { v = sBuffer[i] ^ sBuffer[iLen] ^ sBuffer[iLen-1] ^ cMagic; } else { v = sBuffer[i] ^ sBuffer[i-1]; } // Swap nibbles (0xF0 = 11110000, 0x0F = 00001111) v = (char)(((v << 4) & 0xF0) | ((v >> 4) & 0x0F)); switch(v) { case 0: strcat(sMsg, "/%DCN000%/"); break; case 5: strcat(sMsg, "/%DCN005%/"); break; case 36: strcat(sMsg, "/%DCN036%/"); break; case 96: strcat(sMsg, "/%DCN096%/"); break; case 124: strcat(sMsg, "/%DCN124%/"); break; case 126: strcat(sMsg, "/%DCN126%/"); break; default: strncat(sMsg, (char *)&v, 1); break; } } На старте задается lport как локальный порт хаба, в подключении к хаблисту. У хаблиста порт, естественно, 2501. У нас же, тот что назначит система, а значит случайный. sBuffer - содержит исходный $Lock код. sMsg - по завершении будет содержать нужный $Key код. Теперь собственно код на PHP: Код function lock2key($_LOCK, $port) { $lockLength = strlen($_LOCK); $LockToKey = ''; for ($j = 0; $j < strlen($_LOCK); $j++) { if($j == 0) { $h = ord($_LOCK{0}) ^ 0 ^ ord( $_LOCK{ $lockLength - 1} ) ^ ($port % 256 + ($port>>8) % 256); } else { $h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1}); } $h = $h % 256; $a = (($h<<4) & 240) | (($h>>4) & 15); if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') { $LockToKey .= "/%DCN"; if ($a < 100) $LockToKey .= "0"; if ($a < 10) $LockToKey .= "0"; $LockToKey .= $a; $LockToKey .= "%/"; } else { $LockToKey .= chr($a); } } return $LockToKey; } Из заметных отличий от стандартного следующие: Код $h = ord($_LOCK{0}) ^ 0 ^ ord( $_LOCK{ $lockLength - 1} ) ^ ($port % 256 + ($port>>8) % 256); Используется связка первого символа с нулем (вместо последнего символа), а затем с последним символом (вместо предпоследнего). Также, вместо константы 5, используется магический байт вычисляемый как сумма верхнего и нижнего байта шестнадцетиричного представления номера порта. Все остальные "отличия" - экономия "на спичках" + изменения форматирования, не меняющие алгоритма работы. Функция принимает два параметра, строку $Lock и номер порта. Было бы неплохо этот код обосновать в соответствующей теме, описания протокола. |
|
|
![]()
Сообщение
#2
|
|
![]() Главный ра******й тут... ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Главные администраторы Сообщений: 1 727 Регистрация: 18.5.2008 Из: RF, 2la Пользователь №: 1 Спасибо сказали: 776 раз ![]() |
А код, предоставленный тут для php, - не то? Простите, смотреть в чем различия уже не позволяют слипающиеся глаза...
|
|
|
![]()
Сообщение
#3
|
|
![]() Освоившийся участник ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз ![]() |
Основная проблема заключаеться в том, что этот алгоритм чуть-чуть отличается от обычного. Если быть точным, ровно на первый байт. Под "обычным" и имелось в виду, тот код. Цитируя http://mydc.ru/topic915.html?p=6717#entry6717 Цитата Команда $Key также используется, когда хаб регистрируется в хаб-листе, однако, в этом случае ключ вычисляется по иному. Такой обмен ключами является своего рода гарантом того, что соединяемые устройства работают на одном протоколе.
|
|
|
![]()
Сообщение
#4
|
|
![]() RusHub team lead ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 4 030 Регистрация: 20.6.2008 Из: г. Королёв (Моск. обл.) Пользователь №: 46 Спасибо сказали: 1708 раз ![]() |
Спасибо за детальный разбор алгоритма.
Обязательно обоснуем в описании протокола. |
|
|
![]()
Сообщение
#5
|
|
![]() Освоившийся участник ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 391 Регистрация: 4.11.2009 Из: Дом Пользователь №: 4 923 Спасибо сказали: 239 раз ![]() |
Кстати. Возвращаясь к теме обычного алгоритма. Он не оптимален, да и просто не эстетично записан.
Сейчас: Код function lock2key($_LOCK) { $lockLength = strlen($_LOCK); $h = ord($_LOCK{0}) ^ ord( $_LOCK{ $lockLength - 1} ) ^ ord( $_LOCK{ $lockLength - 2} ) ^ 5; while($h > 255) { $h = $h - 256; } $h = (($h<<4) & 240) | (($h>>4) & 15); $a = $h; if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') { $LockToKey = "/%DCN"; if($a < 100) $LockToKey .="0"; if($a < 10) $LockToKey .="0"; $LockToKey .= $a; $LockToKey .= "%/"; } else { $LockToKey = chr ($a); } for ($j = 1; $j < strlen($_LOCK); $j++) { $h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1}); while($h > 255) { $h = $h - 256; } $h = (($h<<4) & 240) | (($h>>4) & 15); $a = $h; if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') { $LockToKey .= "/%DCN"; if ($a < 100) $LockToKey .="0"; if ($a < 10) $LockToKey .="0"; $LockToKey .= $a; $LockToKey .= "%/"; } else { $LockToKey .= chr ($a); } } return $LockToKey; } А можно так: Код function lock2key($_LOCK, $port) { $lockLength = strlen($_LOCK); $LockToKey = ''; for ($j = 0; $j < strlen($_LOCK); $j++) { if($j == 0) { $h = ord($_LOCK{0}) ^ ord( $_LOCK{ $lockLength - 1} ) ^ ord( $_LOCK{ $lockLength - 2} ) ^ 5; } else { $h = ord($_LOCK{$j}) ^ ord($_LOCK{$j-1}); } $h = $h % 256; $a = (($h<<4) & 240) | (($h>>4) & 15); if($a == '126' or $a == '124' or $a == '96' or $a == '36' or $a == '5' or $a == '0') { $LockToKey .= "/%DCN"; if ($a < 100) $LockToKey .= "0"; if ($a < 10) $LockToKey .= "0"; $LockToKey .= $a; $LockToKey .= "%/"; } else { $LockToKey .= chr($a); } } return $LockToKey; } Имхо, так и компактнее и яснее. |
|
|
![]() ![]() |
Похожие темы
Тема | Ответов | Автор | Просмотров | Последнее сообщение | |
---|---|---|---|---|---|
![]() |
![]() Программа для создания хаблистов |
128 | alex82 | 116 095 | 10.12.2014, 8:32 Посл. сообщение: Nickel89 |
![]() |
![]() Публичный открытый хаблист на PHP |
123 | Enyby | 123 255 | 26.7.2013, 11:46 Посл. сообщение: dj hoodo |
![]() |
От: Tiny Hublist От темы с ID: 4811 |
1 | Артём | 5 847 | 27.12.2011, 15:28 Посл. сообщение: Mellon |
![]() |
От: Public PHP hublist by Enyby От темы с ID: 4961 |
0 | Saymon21 | 5 142 | 20.11.2011, 21:22 Посл. сообщение: Saymon21 |
![]() |
![]() CMS для создания хаблиста. |
62 | Stribog | 70 064 | 14.10.2011, 17:45 Посл. сообщение: KT315 |
![]() |
От: Public PHP hublist by Enyby От темы с ID: 4961 |
1 | Mellon | 5 790 | 12.10.2011, 8:23 Посл. сообщение: Артём |
![]() |
От: Tiny Hublist От темы с ID: 4811 |
1 | STIVAN | 6 199 | 18.4.2011, 20:20 Посл. сообщение: Saymon21 |
![]() |
От: Small DC HubList (Хаблист) От темы с ID: 4709 |
43 | Alexey | 40 163 | 31.3.2011, 19:38 Посл. сообщение: EvilNico |
![]() |
Сейчас: 8.9.2024, 3:05 |