Я наконец-то смог выяснить работу функции Calculate_checksum , и я попытался объяснить это ниже.
Расчет контрольной суммы выполняется следующим образом (согласно RFC1071 ):
Давайте рассмотрим пример.
Если контрольная сумма должна быть вычислена по последовательности октетов [A, B, C, D, E], то будут созданы пары [A, B] и [C, D] с оставшимся октетом E. Пары [a, b] могут быть вычислены следующим образом:
a * 256 + b , где a и b - октеты
Скажите, если a равно 11001010, а b равно 00010001, a * 256 + b = 1100101000010001, что дает нам объединенные результаты октетов.
Таким образом, сумма дополнения 1 вычисляется следующим образом:
sum = [A + B] + '[C + D] +' E, где + 'представляет дополнение 1
дополнение
Теперь вернемся к коду, все перед строкой sum & = 0xffffffff вычисляет сумму дополнения 1, которую мы вычислили ранее.
сумма & = 0xffffffff
используется для усечения суммы до 32 бит, хотя превышение суммы в пинге маловероятно, поскольку размер source_string не очень велик
(source_string = заголовок (8 байт) + полезная нагрузка (переменная длина)).
сумма = (сумма >> 16) + (сумма и 0xffff)
Этот фрагмент кода реализован для случая, когда сумма больше 16 бит. Сумма разбита на 2 части:
(сумма >> 16): 16 битов высшего порядка
(sum & 0xffff): младшие 16 битов
и затем эти две части добавляются. Конечный результат может быть на 16 бит больше, чем на 16 бит
сумма + = (сумма >> 16)
Эта строка используется в том случае, если итоговая сумма, полученная в результате предыдущего вычисления, длиннее 16 битов и используется для выполнения переноса, аналогично предыдущей строке.
Наконец, дополнение 1 вычисляется и усекается до 16 бит. Функция socket.htons () используется для поддержания порядка байтов, отправляемых в сеть на основе архитектуры вашего устройства (с прямым и прямым порядком байтов).