2016-12-07 8 views
1

다음 기술을 식별하는 데 도움이 필요합니다. 읽는 데 시간이 오래 걸리므로 따라하십시오. 내 질문은 이것이 알려진 표준인지, 이름을 가지고 있는지, 누구든지 관련되거나 볼 수 있는지 여부입니다. 이점은 무엇입니까. 또한 궁금한 점이있는 경우에는 오랫동안 잊혀진 온라인 PS2 게임에서 캡처 한 패킷과 관련이 있으며 다시 가져 오려고하는 팀의 일부입니다. 이 표현이 크기는 실제 페이로드 withing에되었으며 클라이언트와 서버 소비되는 IP 프로토콜에 의해 기술 된 바와 같이 크기가 아니다비트 조작 기술 식별에 도움이 필요합니다.

참고. 다음은 메시지의 크기가 표현되는 방식을 설명합니다. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

진정한 패킷 길이는 94 바이트이다. 이것들은 페이로드 데이터의 바이트 5-6 [CF E0]입니다. 또한이 두 바이트를 리틀 엔디안 형식으로 해석해야합니다. 따라서, 우리는

[E0 CF] 우리는 첫 번째 바이트의 첫번째 니블 (4 비트)를 취함으로써이 두 바이트로 패킷 분류를 결정되는 바와 같이이 두 바이트를 생각한다. 이 특별한 경우에 이것은 단지 0xE입니다. 그런 다음이 패킷을 0xE의 패킷 클래스로 식별합니다. 이것은 세션 개시 자 패킷 클래스로 식별되었습니다. 지금

는 나머지 니블과 두 번째 바이트의 패킷 길이를 결정한다. 먼저 두 번째 바이트를 십진수로 변환하면 0xCF = 207이됩니다.이 값과 실제 길이의 차이는 207-94 = 113 바이트입니다. 원래이 바이트가 패킷 길이에 비례한다는 것을 알았지 만 약간의 오프셋이있었습니다. 나는이 오프셋이 어디에서 왔는지 확신하지 못했습니다. 또한이 오프셋은 다른 패킷에 대해 변경된 것으로 보입니다. 더 많은 연구가 필요했습니다.

결국, 나는 각 패킷 클래스는 오프셋 다른 있었다 사실을 발견했다. 그래서 나는 그 패킷 클래스에 대한 오프셋을 계산하기 위해 동일한 패킷 클래스 내의 패킷들만을 조사 할 필요가 있었다. 이렇게하면서, 나는보고 된 모든 길이의 테이블을 만들었고 (바이트 5) 실제 패킷 길이와 비교했다. 내가 발견 한 것은

거의보고 된 모든 패킷 길이의 바이트 5 이상을 0x80 = 128이라고합니다. 다른 바이트의 두 번째 니블은 패킷 길이 에 대한 배율 유형으로 작동하여 각 패킷 클래스가 연관된 최소 패킷 길이와 최대 패킷 길이를 나타낼 수있었습니다. 검토중인 0xC 패킷 클래스의 경우 최소 패킷 크기는 18 바이트이고 최대 패킷 크기는 약 10 * 128 +17 = 1297 바이트입니다. 이렇게하면 다섯 번째 및 여섯 번째 바이트 패킷 헤더에서 패킷 길이를 추출하는 다음과 같은 접근 방식이 사용됩니다. 먼저 패킷 클래스를 0xE로 결정했으며이 패킷 클래스와 관련된 최소 패킷 크기는 15 바이트임을 유의하십시오. 이제,이 경우 첫 번째 바이트 [0xE0] = 0의 두 번째 니블을 가져와 128 바이트 0 * 128 = 0 바이트로 곱합니다. 이제 이것을 두 번째 바이트 [0xCF] = 207에이 경우 추가하고 128을 뺍니다. 따라서 0 + 207 - 128 = 79입니다. 이제이 패킷 클래스의 최소 패킷 크기를 추가해야합니다. 0xE = 15 바이트 최소 패킷 크기 . 따라서 (0 * 128) + (207-128) -15 = 94입니다. 이것은보고 된 실제 패킷 크기입니다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~

이 수식은 20,000 패킷에 후속하는 테스트는 작동시켰다. 그런데 왜 다음 메시지의 크기를 나타내는 데 문제가 있습니까? 나는 그것이 암호화의 한 형태라고 생각했지만 메시지의 나머지는 전혀 암호화되지 않았다. 공식은 이해되지만 이점이 보이지 않습니다.나는 아마 하나의 바이트만을 사용하여 255보다 큰 숫자를 전달함으로써 패킷의 크기를 최적화하는 방법이라고 생각하고있다. 그러나 정확하게 하나의 바이트를 저장하고 다른 바이트를 던지면 65,535의 최대 값을 얻는다. 그래서 다른 바이트를 던지지 않는 이유는 무엇인가? 바이트 스트림에 삽입합니다. 하나의 여분의 바이트가 네트워크에 큰 영향을 미치지 않으므로 어떤 목적이 될 수 있을지 확신합니다. 다른 사람이 문서화 된 표준, 프로토콜, 패턴, 기술 또는 어딘가에 문서화 된 어떤 종류의 문서가 누락되거나 연결되어있는 것을 보게 될지도 모른다고 생각했습니다.

또한 위의 수식을 계산할 때 다른 팀원이 수행 한 것은 아닙니다.

+1

두 번째 바이트에는 비트 7을 항상 설정해야한다는 요구 사항이있을 수 있다고 생각합니다 (예 : 역 호환성). 길이를 처리 할 때 비트 7은 AND 0x7F로 먼저 지워 져야하며, 그렇지 않으면 128을 읽은 바이트 값 (128 = 2 ** 7)에서 빼야합니다. 패킷 길이가 11 비트 바이트 수를 제공하는 byte1 [3 : 0] : byte2 [6 : 0]로 인코딩 된 것처럼 보입니다. 최소 길이는 아마도 인코딩 될 수있는 가능한 길이 값을 최대화하기 위해 빼기됩니다. encode 가능 길이는 [15,15 * 128 + 127 + 15] = [15,2062]입니다. – njuffa

+0

몇 가지 더 많은 예제를 게시하는 것이 유용 할 것입니다. "클래스"가 항상 최소 크기와 같습니까? byte5 bit7 == 0 인 예제가 있습니까? byte6 낮은 니블 비 - 제로가있는 예제가 있습니까? – AShelly

답변

0

가장 좋은 추측은 수신자가 LEB128처럼 가변 길이 base128 인코딩 형식을 사용한다는 것입니다.

그러나이 경우 송신자는 실제 최대 크기가 11 비트에 맞음을 알고 2 바이트를 사용하도록 인코딩하고 "class"에 대해 높은 니블을 오버로드합니다. 이것은 헤더 크기와 생성 시간을 일정하게 만든다. 그리고 수신 측은 클래스를 마스크 처리하여 표준 디코더를 통해 실행할 수 있습니다.

보내기 :

len -= minlen[class] 
byte[5]=(len&0x7F)|0x80; 
byte[6]=(len>>7)|(class<<4); 

는 수신 :

int decode(byte* data) { 
    int v=*data&0x7F; 
    while (*data & 0x80) { 
    data++; 
    v+=*data&0x7F; 
    } 
    return v; 
} 

또 다른 가능성은 [5] 서명 그 바이트이며, 길이는
에 의해 재구성 :

class = byte[6]>>4; 
byte[6]&=0xF; 
len = decode(&byte[5]) + minlen[class]; 

(int8_t)byte[5] + 128*((byte[6]&0xF)+1) + minlen[byte[6]>>4];
그러나 나는 이런 식으로 만들 이유가 없다고 생각합니다.