2014-07-10 6 views
2

원시 패킷을 작성하여 튜토리얼 this 다음에 보내주는 방법을 배우고 있습니다. 체크섬이 생성 된 코드에 도달하기 전까지는 모든 것이 의미가 있습니다.체크섬 및 비트 시프트

unsigned short csum (unsigned short *buf, int nwords) 
{ 
    unsigned long sum; 
    for (sum = 0; nwords > 0; nwords--) 
    sum += *buf++; 
    sum = (sum >> 16) + (sum & 0xffff); 
    sum += (sum >> 16); 
    return ~sum; 
} 

그는 버퍼의 모든 단어를 요약하는 것처럼 보입니다. 하지만 내가 쳤을 때

sum = (sum >> 16) + (sum & 0xffff); 
    sum += (sum >> 16); 

나는 완전히 잃어버린다. 모든 비트를 오른쪽으로 이동하여 이월을 제외한 모든 비트를 삭제 한 다음 원래 합계에 다시 추가하는 것 같습니다. & 0xfff가 필요한 이유는 무엇입니까? 결국, 왜 비트를 다시 수행합니까? 그것은 두 번째 수행 될 수 있기 때문입니까?

+1

오른쪽 시프트 – prajmus

+0

뇌가 분명히 작동을 멈췄습니다 (X – Wusiji

답변

4

라인 :

sum = (sum >> 16) + (sum & 0xffff); 

32 비트 정수에서 좌우의 16 비트 워드를 추가한다. 기본적으로 숫자를 반으로 나누고 두 반쪽을 더합니다. sum >> 16은 왼쪽 절반을 제공하고 sum은 &입니다. 0xffff는 오른쪽 절반을 제공합니다.

그런 다음이 2 개를 함께 추가하면 오버플로가 발생할 수 있습니다. 이 줄은

sum += (sum >> 16); 

원래 숫자에 오버플로를 다시 추가합니다.

0

계산할 체크섬은 16 비트 (unsigned short은 대개 16 비트 임)이지만 변수 sumunsigned long이며 따라서 32 비트가됩니다.

따라서 연산 sum >> 16은 합계의 상위 워드를 캡처하며, 16 비트 이상으로 합쳐진 워드 쌍이 합쳐질 수 있습니다. 그 다음 합계의 낮은 단어 인 sum & 0xffff과 혼합됩니다.

이렇게하면 합계의 모든 비트가 "폴딩되어"최종 결과에 기여하게됩니다.