char数组的RFC 1071校验和

问题描述 投票:2回答:1

我很难理解RFC 1071的以下校验和算法:

The following "C" code algorithm computes the checksum with an inner
loop that sums 16-bits at a time in a 32-bit accumulator.

in 6
{
    /* Compute Internet Checksum for "count" bytes
    *         beginning at location "addr".
    */
    register long sum = 0;

    while( count > 1 )  {
        /*  This is the inner loop */
        sum += * (unsigned short) addr++;
        count -= 2;
    }

    /*  Add left-over byte, if any */
    if( count > 0 )
        sum += * (unsigned char *) addr;

    /*  Fold 32-bit sum to 16 bits */
    while (sum>>16)
        sum = (sum & 0xffff) + (sum >> 16);

    checksum = ~sum;
}

我的目标是获取一个char数组并计算其校验和,但我不确定未定义的变量是什么。什么是addrchecksum的数据类型和/或,我怎么能将char数组转换为可用于校验和过程的格式?我知道count是存储在addr中的任何字节数。

编辑:到目前为止,我正在考虑将char数组转换为整数,然后获取字节数:

int char_int = sscanf(char_array, "%d", &i);
int addr = char_int;
int count = sizeof(char_int);
c checksum
1个回答
3
投票

由于内循环以16位递增的方式处理数据,因此addr必须是指向16位值的指针,即uint16_t * addr

checksum是您希望存储最终结果的数据类型。如果您正在计算16位校验和,那么它也将是uint16_t

请注意,sum应该是unsigned long,而不是long。它在实践中有效,因为网络数据包通常不够大,以至于校验和将溢出long(数据包必须至少为32K字节)。但是,如果您正在编写通用代码,则应该采取防御性编码。

您可以在以下位置找到使用适当的可移植数据类型的实现:

http://www.microhowto.info/howto/calculate_an_internet_protocol_checksum_in_c.html

uint16_t ip_checksum(void* vdata,size_t length) {
    // Cast the data pointer to one that can be indexed.
    char* data=(char*)vdata;

    // Initialise the accumulator.
    uint32_t acc=0xffff;

    // Handle complete 16-bit blocks.
    for (size_t i=0;i+1<length;i+=2) {
        uint16_t word;
        memcpy(&word,data+i,2);
        acc+=ntohs(word);
        if (acc>0xffff) {
            acc-=0xffff;
        }
    }

    // Handle any partial block at the end of the data.
    if (length&1) {
        uint16_t word=0;
        memcpy(&word,data+length-1,1);
        acc+=ntohs(word);
        if (acc>0xffff) {
            acc-=0xffff;
        }
    }

    // Return the checksum in network byte order.
    return htons(~acc);
}
© www.soinside.com 2019 - 2024. All rights reserved.