Вероятно, потому что без модуля было бы очень трудно вставить контрольную сумму. Представь, что ты написал программу. Вы можете написать все сразу, но для получения правильной контрольной суммы вы должны поэкспериментировать.
Давайте предположим, что вы пишете контрольную сумму по модулю 4. Сначала вы сравниваете значение с 0. Вы запускаете программу, но она обнаруживает, что она была подделана. Зачем? Потому что вы не знаете контрольную сумму, пока не напишите весь исходный код. И поскольку в него встроено значение контрольной суммы, каждое изменение исходного кода изменяет контрольную сумму.
Так что это как собака, гоняющаяся за собственным хвостом. Или змея ест свой хвост. Технически говоря, это динамическая система с обратной связью. Хорошо, достаточно аналогий.
Единственный способ заставить это работать - это экспериментировать. Начните с контрольной суммы, равной нулю, и скомпилируйте. Скорее всего, он распознает, что он был подделан (неверно), поскольку у вас есть приблизительно 1/4 вероятности (поскольку любое значение по модулю 4 может иметь 4 значения), чтобы угадать правильно. Затем вы меняете значение на 1. Если это не работает, чем на 2 и, наконец, на 3.
Один из них может совпадать, но наличие низкого значения по модулю снижает вероятность обнаружения взлома. Таким образом, значение 16 в основном является компромиссом. Вы хотите, чтобы значение по модулю было как можно ниже, чтобы иметь достаточно низкое количество догадок. С другой стороны, вы хотите, чтобы алгоритм был достаточно защищен от взлома по модулю.