字符数组的RFC 1071校验和

时间:2019-02-20 22:33:10

标签: c checksum

我很难理解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);

1 个答案:

答案 0 :(得分:3)

由于内部循环以16位为增量处理数据,因此Option Explicit Dim sht As Worksheet, destsht As Worksheet Dim i As Long, j As Long Dim arr As Variant, arr2 As Variant Sub TransferDeliveryInfoB13() Set sht = Sheets("Parts In-Out Form") Set destsht = Sheets("Deliveries") arr = Array(3, 9, 10, 4, 5, 2, 8, 12, 1) arr2 = Array("B13", "C13", "C9", "D13", "F9", "H9", "F12", "H12", "B9") Dim LastRow As Long LastRow = destsht.Cells(Rows.Count, 1).End(xlUp).Offset(1).Row j = 0 For i = 13 To 15 If sht.Range("D9").Value = "In" And sht.Range("B" & i) > 0 Then For j = 0 To UBound(arr) destsht.Cells(LastRow, arr(j)).Value = sht.Range(arr2(j)).Value Next j Else destsht.Protect ("mustache") sht.Range("B9,D9,F9,H9,C9,F12,B12:B42,C12:C42,D12:D42,H12").ClearContents End If Next i End Sub 必须是指向16位值(即addr)的指针。

uint16_t * addr是希望将最终结果存储到的任何数据类型。如果要计算16位校验和,它也将是checksum

请注意,uint16_t应该是sum,而不是unsigned long。它之所以在实践中起作用,是因为网络数据包通常不足以使校验和溢出long(数据包必须至少为32K字节)。但是,如果您要编写通用代码,则应该进行防御性编码。

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

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

long