last day (16 days later) » 

09:27
7
Q: Программа, устойчивая к редактированию

Stanislav VolodarskiyКлиент заказывает Программисту Складыватель. Складыватель читает два целых числа и печатает их сумму. Программист пишет: a, b = map(int, input().split()) print(a + b) Клиент доволен, но он опасается, что программа могла исказиться при передаче. Например, если + случайно заменился на -, программа...

Вот ведь пытливый ум. Так, но если искажение может быть любое, то во многих случаях программа просто не скомпилируется. И, мне кажется, мы с этим ничего сделать не можем. Или нужно бороться только с такими искажениями, которые оставляют программу исполнимой? В этом случае скорее всего кроме знака действия вряд ли что-то ещё можно изменить. А это уже можно будет как-то задублировать, проверить.
@CrazyElf, да, надо бороться только с исполнимыми искажениями. Явное падение хорошо видно.
@CrazyElf, как-то очень тяжело формулируется.
avp
avp
Вот скрипт на sh (bash) проверить довольно просто. Надо вычислить какой-нибудь хэш-код (например, вызвать md5sum) от файла со своим текстом и сравнить его с ранее вычисленным. Наврное и на python (по крайней мере в линукс (см. man proc)) можно проделать то же самое
@avp, если суметь встроить контрольную сумму, то можно сделать довольно устойчиво. С другой стороны print(0);import sys;sys.exit() в первой строке вряд ли преодолим. Но это всё-таки 31 символ. Не так плохо.
А если искажение не приведет к изменениям? Например, вместо scanf("%d%d",&a,&b); printf("%d",a+b); будет cin>>a>>b; cout << a+b;? :)
09:27
@Harry, такие искажения безвредны.
@avp Контрольная сумма очень даже годный вариант. Можно и какой-то хэш от самой суммы возвращать, чтобы его можно было проверить )
А не связана ли эта задача просто с кодами с коррекцией ошибок?...
@CrazyElf Для контрольной суммы нужно написать отдельную часть кода которая будет всё проверять, а её всё так же легко атаковать заменив, например, == на !=
@Harry, возможно, связана. Я так далеко не забирался. :)
@dofi4ka, замена равенства изменит контрольную сумму и будет замечена грамотно написанной программой.
Учитывая, что искажения - это изменение кода и оно может быть сделано не на этапе подсчетов, а прям на этапе возврата результата, то возможным решением видится - юнит тесты в стороннем сервисе + билд там же. Т.е. готовый код передаем в черный ящик, где код запускается и тестируется, а в ответ возвращается собранный исполняемый файл с хэш суммой или ошибка. Причем для определения возможного искажения, сначала тесты провести локально, и передавать на закрытое тестирование не только код, но и сами результаты локального тестирования для сравнения.
09:27
@SwaD, это можно всё в конце концов поместить в файл исходного кода, который будет устойчив к искажениям? Если да, то это решение.
Еще мысль пришла - если результат печатается пользователю - можем ли мы проверить, а что же мы напечатали в итоге? Если можем, то как бы, обратным потоком вернуть рассчитанное значение и проверить на "дубликате" функции результат. Совпал не совпал и уже исходя из этого делать дальнейшие выводы\действия и т.д. Если мы не знаем, что распечаталось у пользователя, то ой...
@SwaD, sys.stdout может быть заменён другим объектом. Ваша идея не лишена смысла.
@SwaD Про тесты у меня, кстати, тоже была идея, но я её забыл написать. Возможно, это вообще самый простой способ проверить, что код не поменялся. Модификаций наверное нужно будет столько же, сколько тестов, если тесты хорошо подобраны.
Можно с тестированием организовать 2-х фазное тестирование. 1й этап - передача исходного кода с результатами тестов локальных. Идут тесты, сверки и т.д., все норм, формируется исполняемый файл. (Учитывая уровень недоверия ко всем в степени параноид) передаем исполняемый файл в сторонний сервис для тестирования и тестим готовый билд - как передать значения для сверки, уже вопрос 10й. Имея 2 "независимых" сервиса тестирования, вариантов пропустить "искажение" становится крайне мало. Главным условием тестирования является то, что разработчик приклада не должен иметь доступ к разработке тестов
Требование "один текстовый файл" является абсолютным? Программа имеет доступ к собственному файлу? Например, можно ли ее скомпилировать и вызвать при получении с передачей в командной строке исходного файла для проверки? И еще - python обязателен?
09:27
@Harry, нет. Вы можете прислать Клиенту несколько файлов и безусловную инструкцию по сборке. "Безусловную" означает что он ей следует, но нигде не принимает решений. В конце инструкции он вводит два числа на одной строке и смотрит что напечатается после. Например вы шлёте два файла и говорите что их надо положить рядом, первый надо скомпилировать gcc, запустить ./a.out, ввести два числа, прочитать ответ.
@Harry, меня не только Питон интересует. Если на C++ вы получите решение, которое переносит 100 искажений, это будет победа. На Питоне пока максимум 19 искажений. И кажется, что выше 22 не поднятся в принципе. На C++ может быть совсем другая история.

  last day (16 days later) »