Рассчитать контрольную сумму Интернета (он же IP, он же RFC791) в C # - PullRequest
2 голосов
/ 03 февраля 2010

Интересно, что я могу найти реализации контрольной суммы в Интернете почти на всех языках, кроме C #. У кого-нибудь есть реализация, которой можно поделиться?

Помните, что интернет-протокол указывает, что:

"Поле контрольной суммы является 16-битным дополнением к одному дополнить сумму всех 16-битных слов в заголовке. Для целей вычисляя контрольную сумму, значение поля контрольной суммы равно нулю. "

Больше объяснений можно найти у Д-р. Math .

Есть несколько доступных указателей эффективности , но на данный момент это меня не особо беспокоит.

Пожалуйста, включите ваши тесты! (Редактировать: действительный комментарий относительно тестирования чужого кода - но я отключаю протокол и у меня нет собственных тестовых векторов, и я предпочел бы выполнить его модульное тестирование, чем запустить в производство, чтобы увидеть, соответствует ли он тому, что используется в настоящее время! ; -)

Редактировать: Вот некоторые модульные тесты, которые я придумал. Они тестируют метод расширения, который перебирает всю коллекцию байтов. Пожалуйста, прокомментируйте, если вы обнаружите ошибку в тестах.

[TestMethod()]
public void InternetChecksum_SimplestValidValue_ShouldMatch()
{
    IEnumerable<byte> value = new byte[1]; // should work for any-length array of zeros
    ushort expected = 0xFFFF;

    ushort actual = value.InternetChecksum();

    Assert.AreEqual(expected, actual);
}

[TestMethod()]
public void InternetChecksum_ValidSingleByteExtreme_ShouldMatch()
{
    IEnumerable<byte> value = new byte[]{0xFF};
    ushort expected = 0xFF;

    ushort actual = value.InternetChecksum();

    Assert.AreEqual(expected, actual);
}

[TestMethod()]
public void InternetChecksum_ValidMultiByteExtrema_ShouldMatch()
{
    IEnumerable<byte> value = new byte[] { 0x00, 0xFF };
    ushort expected = 0xFF00;

    ushort actual = value.InternetChecksum();

    Assert.AreEqual(expected, actual);
}

Ответы [ 2 ]

4 голосов
/ 03 февраля 2010

Я знал, что этот где-то хранился ... http://cyb3rspy.wordpress.com/2008/03/27/ip-header-checksum-function-in-c/

1 голос
/ 04 февраля 2010

Ну, я откопал реализацию из старой базы кода, и она прошла тесты, которые я указал в вопросе, так что вот (как метод расширения):

public static ushort InternetChecksum(this IEnumerable<byte> value)
{
    byte[] buffer = value.ToArray();
    int length = buffer.Length;
    int i = 0;
    UInt32 sum = 0;
    UInt32 data = 0;
    while (length > 1)
    {
        data = 0;
        data = (UInt32)(
        ((UInt32)(buffer[i]) << 8)
        |
        ((UInt32)(buffer[i + 1]) & 0xFF)
        );

        sum += data;
        if ((sum & 0xFFFF0000) > 0)
        {
            sum = sum & 0xFFFF;
            sum += 1;
        }

        i += 2;
        length -= 2;
    }

    if (length > 0)
    {
        sum += (UInt32)(buffer[i] << 8);
        //sum += (UInt32)(buffer[i]);
        if ((sum & 0xFFFF0000) > 0)
        {
            sum = sum & 0xFFFF;
            sum += 1;
        }
    }
    sum = ~sum;
    sum = sum & 0xFFFF;
    return (UInt16)sum;
}
...