Существуют ли какие-нибудь умные алгоритмы для вычисления высококачественных контрольных сумм на миллионы или миллиарды простых чисел? То есть с максимальной способностью обнаружения ошибок и, возможно, с возможностью сегментирования?Контрольные суммы больших частей простых чисел? (для проверки)
Мотивация:
Маленьких простые числа - до 64 бит в размерах - может быть просеивают по требованию на сумму миллионов в секунду, с помощью небольшой битовой карты для просеивания потенциальных факторов (до 2^32-1) и вторую растровую карту для просеивания чисел в целевом диапазоне.
Алгоритм и реализация достаточно просты и понятны, но дьявол находится в деталях: значения имеют тенденцию нажимать или превышать пределы встроенных интегральных типов везде, граничные случаи изобилуют (так сказать) и даже различиями в плавающих точная строгость может привести к поломке, если программирование недостаточно защищено. Не говоря уже о хаосе, который оптимизирующий компилятор может нанести, даже на уже скомпилированный, уже проверенный код в статическом lib (если используется генерация кода времени привязки). Не говоря уже о том, что более быстрые алгоритмы, как правило, намного сложнее и, следовательно, еще более хрупкие.
Это имеет два последствия: результаты испытаний в основном бессмысленны, если тесты не выполняются с использованием окончательного исполняемого изображения, и очень желательно проверить правильную работу во время выполнения во время обычного использования.
Проверка на заранее рассчитанные значения даст наивысшую степень уверенности, но требуемые файлы являются большими и неуклюжими. Текстовый файл с 10 миллионами простых чисел имеет порядок 100 МБ несжатого и сжатие более 10 МБ; для хранения байтовых кодировок требуется один байт на штрих-код, а энтропийное кодирование может в лучшем случае уменьшить размер до половины (5 МБ для 10 миллионов простых чисел). Следовательно, даже файл, который покрывает только малые факторы до 2^32, будет весить около 100 МБ, а сложность декодера будет превышать сложность самого оконного решета.
Это означает, что проверка файлов невозможна, за исключением проверки окончательной версии для вновь созданного исполняемого файла. Не говоря уже о том, что надежные файлы нелегко найти. Prime Pages предлагают файлы для первых 50 миллионов простых чисел, и даже удивительные primos.mat.br идут только до 1 000 000 000 000. Это печально, так как многие граничные случаи (== потребность в тестировании) происходят между 2^62 и 2^64-1.
Это оставляет контрольные суммы. Таким образом, требования к пространству будут незначительными и будут только пропорциональны количеству тестовых случаев. Я не хочу требовать наличия приличной контрольной суммы, такой как MD5 или SHA-256, и с целевыми номерами, которые являются основными, должно быть возможно создать высококачественную контрольную сумму с высоким разрешением с некоторыми простыми операциями с номерами самих себя.
Это то, к чему я придумал. Исходный дайджест состоит из четырех 64-битных номеров; в конце его можно сложить до желаемого размера.
for (unsigned i = 0; i < ELEMENTS(primes); ++i)
{
digest[0] *= primes[i]; // running product (must be initialised to 1)
digest[1] += digest[0]; // sum of sequence of running products
digest[2] += primes[i]; // running sum
digest[3] += digest[2] * primes[i]; // Hornerish sum
}
В двух (не зависимых) мулов в расцвете сил скорость приличная достаточно, и для простой суммы, за исключением каждого из компонентов всегда раскрыли все ошибки я пытался прокрасться мимо дайджеста. Однако я не математик, и эмпирическое тестирование не является гарантией эффективности.
Существуют ли некоторые математические свойства, которые можно использовать для проектирования, а не «повар», как я, - разумная, надежная контрольная сумма?
Возможно ли сконструировать контрольную сумму таким образом, чтобы она была ступенчатой, в том смысле, что поддиапазоны могут обрабатываться отдельно, а затем результаты, объединенные с небольшим количеством арифметических действий, дают такой же результат, как если бы весь диапазон был контрольная сумма за один раз? То же самое, что и все современные реализации CRC, как правило, имеют в настоящее время, чтобы обеспечить параллельную обработку.
EDIT Обоснование текущей схемы заключается в следующем: количество, сумма и произведение не зависят от порядка, в котором простые числа добавляются в дайджест; они могут быть вычислены на отдельных блоках, а затем объединены. Контрольная сумма зависит от порядка; это его смысл. Однако было бы неплохо, если бы две контрольные суммы двух последовательных блоков могли быть объединены так или иначе, чтобы дать контрольную сумму объединенного блока.
Количество и сумма иногда может быть проверена от внешних источников, как некоторые последовательности на oeis.org, или против источников, таких как партии 10 миллионов простых чисел в primos.mat.br (индекс дает первый и последний штрих, число == 10 миллионов подразумевается). Однако такой удачи для продукта и контрольной суммы.
Перед тем, как выбросить большое время и вычислительную мощность при вычислении и проверке дайджестов, охватывающих весь спектр малых факторов до 2^64 Я хотел бы услышать, что думают эксперты об этом ...
схема Я в настоящее время тест-драйв в 32-битном и 64-битном варианте выглядит следующим образом:
template<typename word_t>
struct digest_t
{
word_t count;
word_t sum;
word_t product;
word_t checksum;
// ...
void add_prime (word_t n)
{
count += 1;
sum += n;
product *= n;
checksum += n * sum + product;
}
};
Это имеет то преимущество, что 32-разрядные переваривать компоненты равны нижней половинах соответствующего 64 что означает, что только 64-битные дайджесты должны быть вычислены, даже если требуется быстрая 32-битная проверка. 32-битную версию дайджеста можно найти в этом простом sieve test program @ pastebin для практических экспериментов. Полный Monty в пересмотренной, шаблонизированной версии можно найти в новой пасте для a sieve that works up to 2^64-1.
По общему признанию, я в основном проигнорировал ваш запрос на хеш-функцию, которая обладает некоторыми более сильными свойствами, чем обычные функции дайджеста, и торгует тем, как вы можете сделать любую функцию дайджеста по вашему выбору параллелизуемой. Но при этом вы, вероятно, выбрасываете какие-либо интересные свойства более хеш-функции с более сильной собственностью. – Kaganar
Ваш ответ очень интересный и продуманный. Это не совсем решает проблему, как указано, поскольку она требует некоторой сложной хэш-функции, сложность которой находится в порядке MD5 или SHA-256, и она не использует специальные свойства ввода (все простые числа). Однако ваше решение отлично решает несколько более общую проблему: хеширование больших фрагментов памяти в сепарабельном (парализуемом/степямом) способе, даже если основная хеш-функция не является степенной (в отличие от CRC, где вы можете использовать линейную алгебру для сшивайте результаты для последовательных блоков вместе) – DarthGizka
Следовательно, я награждаю награду за ваш отличный ответ, а также с учетом того факта, что эксперты, привлеченные здесь по этому вопросу, могут ожидать найти что-то подобное. Я очень люблю Мурмурхаша, и деревья Меркле несколько раз спасли мою задницу. Деревья Merkle естественным образом подходят для проблемы в том смысле, что одно предполагаемое применение дайджеста должно охватывать диапазон 0..2^64-1 примерно таким же образом, как B-Tree, путем добавления результатов по мере их появления и проверено. Объектом является возможность последующей проверки без хранения терабайт данных. – DarthGizka