Вдохновленный этим комментарием ...
Спасибо пользователям Step Hen , Wheat-Wizard и Dennis за помощь в разработке спецификации этого задания перед его публикацией!
Это нить грабителя! Для нити ментов, иди сюда
В этом задании перед вами стоит запуск некоторого кода, который делает его так, чтобы ваш язык больше не удовлетворял нашим критериям языка программирования. В этом вызове это означает сделать так, чтобы язык больше не мог ...
Возьмите числовой ввод и вывод
Добавьте два числа вместе
Проверьте, является ли определенное число простым или нет.
Это задача полицейских и грабителей , где есть две разные задачи с двумя разными целями: копы попытаются написать некоторый код, который делает язык в основном непригодным для использования, а грабители попытаются найти скрытый обходной путь, который позволяет копам восстановить свой язык.
Полицейские напишут два фрагмента кода:
Тот, который делает их язык в основном непригодным, например, удаляя встроенные функции для ввода / вывода и числовые операции. Этот код не может произойти сбой или выход. Должна быть возможность добавить код в конец этого фрагмента, и этот код будет оценен . А также
Фрагмент кода, который принимает два числа в качестве входных данных, складывает их вместе и выводит их сумму. Этот фрагмент должен работать правильно даже после запуска первого фрагмента. Когда два фрагмента объединены вместе, они должны сформировать полную программу, которая добавляет два числа, или определить функцию, которая добавляет два числа. Этот фрагмент, вероятно, будет опираться на неясное поведение, и его будет трудно найти.
Полицейские также выберут любой стандартный метод ввода и вывода . Однако они должны точно указывать, какой формат (входной и выходной) они используют. Чтобы вы могли взломать их ответ, вы должны следовать тому же формату ввода / вывода, иначе ваш взлом не будет учитываться.
Ответ ментов всегда откроет
Первый фрагмент (явно не второй).
Язык (включая минорную версию, так как большинство представлений, вероятно, будет опираться на странные крайние случаи)
Формат ввода-вывода, в том числе ли это функция или полная программа. Грабители должны использовать тот же формат, чтобы быть действительным взломом.
Любые странные крайние случаи, необходимые для их ответа на работу. Например, работает только на Linux или требует подключения к Интернету .
Как грабитель, вы должны посмотреть на одно из представлений полицейских и попытаться взломать его. Вы можете взломать его, написав любой допустимый фрагмент кода, который мог бы работать как фрагмент 2 (сложение двух чисел после того, как язык стал в основном непригодным для использования). Это не должен быть тот же фрагмент, который первоначально написал полицейский. После того, как у вас есть взломанный ответ, опубликуйте свой код как ответ в этой теме и опубликуйте ссылку на свой ответ в качестве комментария к ответу полицейского. Затем это сообщение будет отредактировано, чтобы указать, что оно взломано.
Вот пример. Для первого фрагмента вы можете увидеть следующую программу на Python 3 в качестве ответа полицейского:
Python 3
print=None
Принимает ввод из STDIN и вывод в STDOUT
Допустимый второй фрагмент может быть
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
Это верно, потому что он будет принимать два числа в качестве входных данных и выводить их сумму, даже если вы соедините два фрагмента вместе, например
print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
Это действительный треск к их ответу.
Если ответ копа остается без изменений в течение целой недели, он может отредактировать свой второй фрагмент и указать, что его ответ теперь безопасен . После того, как он отредактирован, чтобы быть безопасным, вы можете больше не пытаться взломать его. Если они не редактируют это как безопасное, вы можете продолжать пытаться взломать его, пока они не сделают это.
Победителем темы грабителя является пользователь, взломавший наибольшее количество ответов, причем тай-брейк - это время, когда они достигли N трещин. (например, если два разных пользователя имеют по 5 крэков, например, пользователь, который первым разместил свой 5-й крэк, является победителем). По истечении достаточного времени я приму ответ победителя с наибольшим количеством голосов.
Повеселись!
Разъяснения правил
Первый фрагмент должен работать правильно, без каких-либо входных данных . Он может выводить все, что угодно, и этот вывод будет игнорироваться. Пока этот фрагмент готов, второй фрагмент работает правильно.
Второй фрагмент должен быть действительно выполнен, чтобы ваш ответ был действительным. Это означает, что ответ как
import sys sys.exit()
недопустимо, потому что это не нарушает язык. Это просто выходит.
После того, как вы в безопасности, ваш счет - это количество байтов обоих фрагментов .
Это восходит к Пожалуйста , выявить какие - либо странные случаи края , необходимые для ответа на работу ... Ваша заявка должна содержать достаточно информации , прежде чем раскрывается воспроизводимыми после раскрывается. Это означает, что если ваш ответ станет безопасным, а затем вы отредактируете в: Вот мой ответ. Да, кстати, это работает, только если вы запускаете его на Solaris, шутки над вами! Ваш ответ недействителен и будет удален и не будет признан приемлемым для победы.
Второй фрагмент может потерпеть крах после вывода суммы. Пока вывод по-прежнему правильный (например, если вы выберете вывод в STDERR, а затем получите кучу информации о сбое, это недопустимо)
Leaderboard
Вот список каждого пользователя, у которого есть хотя бы один треск, упорядоченный по счету, а затем по имени (в алфавитном порядке). Если вы отправите трещину, пожалуйста, обновите ваш счет соответственно.
#User #Score
Ilmari Karonen 8
Dennis 5
Olivier Grégoire 4
Sisyphus 3
Veedrac 3
Arnold Palmer 2
Bruce Forte 2
DJMcMayhem 2
Dom Hastings 2
ppperry 2
1bluston 1
2012rcampion 1
Ben 1
BlackCap 1
Christian Sievers 1
Cody Gray 1
HyperNeutrino 1
Joshua 1
Kaz 1
Mark 1
Mayube 1
Xnor 1
zbw 1
источник
SecurityManager
который был в области видимости ... Вы также можете прочитать сSystem.in
этого момента, потому что он еще не закрыт.sun.awt.SecurityManager
и"sun.awt.command"
зависят от платформы и не являются частью Java .System.getProperties().get("blah")
(так как я только заблокировал доступSystem.getProperty
, неSystem.getProperties
), но этого достаточно хорошо! Отлично сработано!C (GCC / Linux) от Sisyphus
Этот фрагмент закрывает предоставленную функцию и запускает новую (классическая инъекция кода), которая сама по себе переопределяет,
close
так что вместо закрытия fd запускается наш нужный код.источник
Python, решение для мастера по пшенице здесь
Я имею в виду, вы можете просто установить предел рекурсии, и ничего плохого не случится ...
Работает на TIO
Заметка
Это моя первая CnR-заявка, поэтому, если это нарушает какие-либо правила, пожалуйста, сообщите мне, и я удалю это.
источник
os.sys
, если это имеет значение: PХаскель Бен
У меня все еще есть буквальные числа и символы (я использую
0
,'0'
и'-'
),[a..]
и[a..b]
которые очень полезны. И у меня одинарные-
, но я мог бы обойтись без.Я воссоздаю
++
для реализацииr
(reverse
) и определить,t
аts
какиеtail
иtails
.x a b
возвращаетn
элемент thb
, гдеn
длинаa
минус один.x
обычно можно определить какsnd.last.zip
. Функцияd
берет список и возвращает список с элементами из тех позиций, которые кратны десяти.l!!s
возвращаетn
элемент thl
, гдеs
- обратное строковое представлениеn
.+
возвращает в виде целого числа сумму двух натуральных чисел, заданных в виде перевернутых строк, аналогично-
разнице.add
возвращает как целое число сумму двух возможно отрицательных целых чисел, заданных в виде строк.Интересно, похоже ли это на то, что имел в виду Бен.
источник
:
был в объеме дажеNoImplicitPrelude
без импорта.C (GCC) Конор О'Брайен
Попробуйте онлайн!
источник
Python 2 от Wheat Wizard (четвертая итерация)
Попробуйте онлайн!
Никаких эксплойтов, только функция для добавления с использованием только символов
' &)(,.:[]a`cdfijmonrt~'
, как задумано (на самом деле только'(),.:[]`acdfijmnort'
).Я не пытался сделать это коротким; Я только что написал подвыражения для промежуточных значений, таких как 0, а также пустые строки и подставленные в них строки.
Попробуйте онлайн!
Основная идея заключается в том, что формат строки
'{0:5}'.format('1')
дополняет число от нуля до длины5
подобия'1 '
. Путем объединения двух таких строк''.join
, сумма их длины равна сумме входных чисел. Затем мы добавляем a0
до конца и вызываем.find()
конечную позицию, которая является суммой.Строка
'{0:5}'
для форматирования создается путем извлечения{:}
символов из строковых реплик словарей, созданных с помощьюdict
. Строка repr каждого последующего слагаемого размещается там, где будет 5. Я хотел использовать диктовку, подобную{0:5}
самой себе, но его репр содержит пробел, который испортил его.Входы 0 запутывают процесс, потому что строка sub имеет минимальную длину 1. У нас есть те, у которых есть
and/or
пустая строка в этом случае.источник
int([]in[])
просто иint()
как выход будет 0.Хаскель, Лайкони
источник
16-битная сборка в реальном времени x86, автор Joshua
Объяснение:
«Обрыв», введенный кодом Джошуа, - это установка флага ловушки (TF), который переводит ЦП в одношаговый режим. Это означает, что одновременно будет выполняться только одна инструкция, прежде чем процессор остановится (перехватит) с прерыванием типа 1. Это то, что позволяет отладчикам реализовывать пошаговый код, что очень удобно, но настоящая PITA, если вы хотите запустить код вне контекста отладчика!
Это следующий раздел кода, который включает флаг прерывания:
Реализация флага trap-сообщения означает, что у нас есть шанс выполнить ровно одну инструкцию до того, как процессор перехватит ловушку - это та, которая приходит сразу после
POPF
here. Итак, нам нужно сделать это один счет.Уловка -
INT 3
инструкция, которая вызывает прерывание номер 3. Есть две причины, почему это работает, чтобы "разорвать" код:Флаг прерывания сбрасывается в обработчиках прерываний. Это всего лишь часть дизайна Intel, но, по-видимому, это было сделано по причинам здравого смысла. Помните , что реализация флага ловушки является то , что прерывание типа 1 вызывается после выполнения каждой команды, так что если TF не был очищен,
INT 1
будет сам инициировать прерывание, было бы перебивает весь путь вниз. Кроме того, наличие четких прерываний TF просто облегчает отладку кода, подобно IDE, которая автоматически переходит к вызовам библиотечных функций.Способ прерывания работы по сути такой же, как и дальний
CALL
. Они вызывают обработчик прерывания, адрес которого хранится в соответствующей позиции в глобальной таблице векторов прерываний. Поскольку эта таблица начинается с адреса0x0000:0000
и хранится в 4-байтовомsegment:offset
формате, вычислить адрес так же просто, как умножить 4 на вектор / номер прерывания. В этом случае мы вызываем прерывание 3, так что это будет 4 × 3 = 12.... и вы заметите, что Джошуа задумчиво настроил это для нас. До включения флага ловушки он имеет следующий код:
который устанавливает
0x0000:000C
(обработчик прерыванияINT 3
) вBP:SI
. Это означает, что всякий раз, когдаINT 3
вызывается, он помещает регистр FLAGS в стек, за которым следует адрес возврата, а затем переходит к немуBP:SI
, что позволяет нам снова начать выполнение кода в контексте, где флаг прерывания отключен.Это все вниз после
INT 3
. Все, что нам нужно сделать, это сложить вместе два числа и напечатать результат. За исключением того, что на ассемблере это не так просто, как на других языках, так что именно на этом тратится основная часть кода.Джошуа позволяет грабитель указать любой механизм ввода / вывода (ов) он хочет , так что я беру упрощенный подход в предположении , что значения передаются в
DX
иCX
регистрах. Это разумно, поскольку они нигде не засорены его «прологовым» кодом.Вывод выполняется путем сохранения байтов ASCII непосредственно в видеопамять. Видеобуфер начинается
0xB800:0000
с текстового режима CGA, EGA и / или VGA, поэтому мы начинаем печать там. Формат: символ в младшем байте и атрибут цвета в старшем байте. Это означает, что каждый символ имеет смещение в 2 байта. Мы просто перебираем каждую из цифр в номере (base-10), конвертируем их в ASCII и печатаем их по одному на экран. Да, это много кода. Там нет библиотечных функций, которые помогут нам в ассемблере. Это почти наверняка можно оптимизировать дальше, но я устал работать над этим ...После того, как выходные данные отображаются, коду разрешается сбой или что-либо еще, поэтому мы просто очищаем прерывания и останавливаем процессор.
источник
INT 3
и сразу же возвращаюсь к следующей инструкции, поэтому я просто пошел с ней. Может быть, это как-то связано с моей средой тестирования?CLI
будет отключать только аппаратные прерывания, но даже если онHLT
пройдет, вы можете подумать, что он провалится и выполнит кодl
сразу после этого.Python 2 от TwiNight
Попробуйте онлайн!
источник
Python 3 , 2 - й вызов ppperry
Вау, это было весело! Мне понравилось это решать.
Редактировать: ОК, я исправил это. Кажется, что классы в списке подклассов в TIO отличались от индекса, отличного от моего компьютера, поэтому я заставил их работать для обоих и добавил TIO.
Попробуйте онлайн!
источник
sys.excepthook is missing
?sys.excepthook
, но где-то там будет указана реальная причина.)IndexError('list index out of range',)
. Это на линии с определением_io_RawIOBase
._io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]
должен работать везде.Haskell от zbw
Не можете запустить код во время выполнения? Запустите его во время компиляции!
Это было очень весело, я не знал шаблона haskell до этого испытания.
источник
Желе по гипер нейтрино
Супер просто. Новая строка приводит к тому, что первая ссылка не вызывается.
Попробуйте онлайн!
источник
Python 2 от Wheat Wizard
Попробуйте онлайн!
источник
Java от LordFarquaad
Блокировка доступа к объектам на исходном уровне была действительно умной (и раздражающей при тестировании), молодец!
источник
ClassLoader
бы был в тени?"".getClass().getClassLoader()
. Затенение обычно является только проблемой, о которой вам нужно подумать один раз, и тогда все в порядке. Вы могли бы даже теньObject
, я все еще смогу решить это. Хорошо, вы могли бы заставить меня в 1kb решение, но это возможно.Рубин гистократ
Попробуйте онлайн!
источник
Информ 7, Илмари Каронен
Грубое злоупотребление двусмысленными существительными ... Мой код начинается с
factory is a room
. Предыдущая строка - это код полицейского. Напечатайте,add 1 and 1
чтобы получить 2, например.источник
Ява, Роман Греф
Устанавливается
stdout
иstderr
возвращается к своим начальным значениям.Я считаю, что я могу использовать полное имя вместо импорта, если я ошибаюсь, поправьте меня (это мой первый пост здесь). Возможно, это можно сделать и с помощью рефлексии.
Изменить: вот рефлексивное решение, используя только
java.lang.reflect.*
:источник
stdin
,stdout
иstderr
хранятся в другом месте! Вам даже не нужно использоватьsetOut
и,setErr
как вы можете просто использоватьPrintStream
напрямую.JavaScript от Даниэль Франклин
Это может считаться немного обманчивым решением, но оно работает для меня на Chromium 59 / Linux, даже если я также получаю предупреждение:
Ps. Вот еще один треск, на этот раз без предупреждений:
источник
prompt()- -prompt()
сохраняет два байтаJava 8 Оливье Грегуар
Чрезвычайно многословная трещина для чрезвычайно многословного испытания. :) Боль косвенной работы с классами, которые вы не можете назвать, ощутима.
Попробуйте онлайн!
Ps. Вот моя более ранняя попытка, написанная до того, как Оливье пояснил, что ввод должен был осуществляться через аргументы командной строки. В отличие от рассмотренного выше трека, этот не специфичен для Linux.
Попробуйте онлайн!
источник
String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");
, которое не зависит от Linux, но использует то, что кажется недокументированным свойством, установленным некоторыми JVM.C # (.NET Core) разнагул
Я предполагаю, что это не было намеченным решением.
источник
/dev/std*
этим. Первоначально я стремился к подобному подходу, но не мог найти простой способ открыть потоки для stdin / out без доступа к System.Console, поэтому вместо этого я выбрал рефлексию. Конечно, ваше решение предположительно работает только в Linux и других системах Unixish с соответствующими/dev
записями, но Разнагул не сказал, что оно должно работать в Windows. И это работает на TIO.Java, по racer290
Это было довольно простое упущение, что
static
инициализаторы вызываются передmain
методом. Это была хорошая попытка:throw new Error()
сначала я был встревожен , но в конце концов нашел путь;)источник
System.out.println("Hello World!");
Не добавляет два целых числа? .. " 2. Фрагмент кода, который принимает два числа в качестве входных данных, складывает их вместе и выводит их сумму. Этот фрагмент должен работать правильно даже после запуска первого фрагмента. Когда два фрагмента в сочетании друг с другом, они должны сформировать полную программу , которая добавляет два числа, или определить функцию , которая добавляет два числа Этот фрагмент, вероятно , полагаться на неясного поведение, и трудно найти.. "Java от Кевина Круйссена
Хорошо построен. Много кода, чтобы заставить любого должным образом задуматься, как решить эту проблему. Я полагаю, что «поставить свой код потом» было большим, большим намеком.
Попробуй это здесь.
источник
JavaScript от Гранта Дэвиса
Работает в консоли JS на
about:blank
странице (как указано в посте полицейского) в Chromium 59 / Linux.источник
cQuents , Step Hen , 3 байта
Попробуйте онлайн!
Много говорил с Step Hen, чтобы выяснить, как, черт возьми, работает его странный язык, но вкратце:
Его код был
#|1,1:A
.#|1,1
является вводом по умолчанию, означающим, что любой ввод данных программе добавляется 2 1. (То есть, если вы передаете 47 и 53, ваш ввод[47, 53, 1, 1]
.:
просто устанавливает режим, который будет выводитьn
th-й элемент в последовательности, еслиn
он установлен, и в противном случае выводит всю последовательность.Наконец
A
получает первый вход.Поскольку у нас есть 4 входа
[47, 53, 1, 1]
, добавлениеBC
в конец также извлечет 2-й и 3-й входы, а 4-й ввод неявно становитсяn
.Поскольку наша последовательность
ABC
разбирается алгебраически, то есть становитсяA*B*C
. Мы не хотим этого, но если мы вставим a+
между A и B, оно становитсяA+B*C
, гдеA
иB
являются нашими входами, иC
равно 1.источник
how the hell his weird language works
возможно, как только я закончу это, это может иметь некоторый смыслC # (.NET Core) разнагул
Попробуйте онлайн!
Это, вероятно, заняло бы меньше времени, если бы я действительно знал C #. Однако, с некоторым просмотром документации и небольшой помощью от Джона Скита , мне удалось собрать кое-что, что работает.
источник
Vim Challenge от @DJMcMayhem
Прошло много времени с тех пор, как я не смог выйти из vim , вот мое решение (обратите внимание, что это намного больше, чем
23
байты - так что, вероятно, это не предполагаемое решение):Попробуйте онлайн!
Идея состоит в том , чтобы просто трубы два целых чисел с
awk
помощьюbash
, так=
и+
отключенный мне пришлось использовать небольшие обходным.awk
Линия расширяется:Изменить : Первоначально предполагалось, что ввод уже находится в буфере, но это не будет более сложным - основная трудность заключалась в том, чтобы заставить сложение работать.
Вот предлагаемое исправление @DJMcMayhem: попробуйте онлайн!
источник
[insert your number here]
в режиме вставки. Вместо этого он уже находится в буфере. Но вы можете обойти этоOecho "<esc>Go"|awk...
, так что я думаю, что это имеет значение. Красиво сделано! Это не та кряка, которую я имел в виду (я надеялся на чистый ответ vim), поэтому я, вероятно, опубликую новый ответ, который исправляет внешние команды и!
.Java 7 от Poke
Попробуйте онлайн!
Никаких специфических трюков для Linux не требуется, просто маскировка неквалифицированных
String
иSystem
имен классов. Это, вероятно, не предполагаемое решение, но оно работает.источник
GolfScript Илмари Каронен
Попробуйте онлайн!
источник
RProgN2 от @ATaco
Попробуйте онлайн!
Это далеко не лучший ответ, который я мог бы дать, но он позволяет снова складывать числа. Если бы я на самом деле прошел и сделал правильную обработку стека, я бы, наверное, немного играл в гольф, но на данный момент я доволен ответом.
В оригинальном посте ATaco он фактически просто переназначил все основные арифметические операторы, чтобы уничтожить их входные данные. Чтобы исправить эту проблему, я переопределил, что было добавление в терминах его двоичных операций, что было проблемой, потому что RProgN2 не имеет двоичного оператора отрицания или xor.
Примечание: Если вы хотите проверить ввод, числа с более чем одной цифрой должны быть в форме
"XX..." n
для преобразования в фактическое число, так как RProgN2 принимает каждый символ как есть, если это не концепция или строка. Редактировать: @ATaco отметил, что добавление «$» перед многозначным числом будет делать то же самое.РЕДАКТИРОВАТЬ: Вот логика для моего решения. Как видите, определенно не самый изысканный код, но он работает.
источник
56$46$12
, подтолкнет числа 5, 6, 46 и 12. ЯJavaScript (Node.js) от jrich , 298 байт
Я чувствую, что это не предполагаемое решение, но, если оно, хорошо, я потратил некоторое время, пытаясь выяснить, как получить имя объявленной функции! :)
Попробуйте онлайн!
источник