使您的语言*大部分*无法使用!(警察的线)


61

受到此评论的启发...

多亏了用户Step HenWheat-WizardDennis,他们在发布之前帮助我巩固了这一挑战的规格!

这是警察的话题。有关强盗的线索,请转到此处


这个挑战中,您需要运行一些代码来使您的语言不再满足我们成为编程语言的条件。在这一挑战中,这意味着要做到这一点,以便不再能使用该语言...

  • 进行数字输入和输出

  • 将两个数字相加

  • 测试某个数字是否为质数。

这是挑战,其中有两个不同的挑战,目标是两个不同:警察将尝试编写一些使该语言几乎不可用的代码,而强盗将尝试找到允许警察使用的隐藏变通方法恢复他们的语言。

作为警察,您必须编写两个代码段:

  1. 一种使您的语言几乎不可用的方法,例如,通过删除用于进行输入/输出和数字运算的内置函数。您删除的功能越多越好。此代码是不是允许崩溃或退出。应该可以在此代码段的末尾添加代码,并且该代码将得到评估。和...

  2. ...将两个非负整数作为输入,将它们加在一起并输出其和的代码段。即使运行第一个代码段后,该代码段也必须仍然能够正常运行。当两个代码片段组合在一起时,它们必须形成一个将两个数字相加的完整程序,或者定义一个将两个数字相加的函数。理想情况下,此代码段应依赖于非常晦涩的行为,以便更难找到。

您可以选择任何标准的输入和输出方法。但是,您必须准确显示所使用的格式(输入和输出)。除非他们使用与您相同的格式,否则强盗无法破解您的答案。

编写完这两个片段后,您必须发布第一个片段作为答案,而不必透露第二个片段。您的答案应包含以下所有信息:

  • 一个摘要(显然不是第二个)。

  • 语言(包括次要版本,因为大多数提交可能都依赖于奇怪的情况)

  • IO格式,包括功能或完整程序。强盗必须使用相同的格式来使破解生效。

  • 任何奇怪的情况下,您的答案才能起作用。例如,仅在linux上运行,或者需要Internet连接。显然,这是有点主观的,但是如果警察具有某种极端的边缘情况以防止其破裂,然后仅在安全后才显示出来,我认为这是差劲的运动精神。潜在的抢劫犯应该掌握所有必要的信息,以便在破解之前将其破解。

除非您的答案是安全的,否则您无需透露字节数。

这是一个例子。对于第一个代码段,您可以提交以下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)

但是,这对于抢劫犯来说非常容易找到解决方案。由于这很容易破解,因此您可以尝试修补这种特定方法,如下所示:

import sys
sys.stdout=None
print=None

但是,即使这样也有非常简单的解决方法:

del print
a,b=int(input()),int(input())
print(a+b)

作为警察,您的目标是使隐藏的变通办法尽可能模糊,以防止强盗找到它。

劫匪会看你的答案之一,并试图破解它。他们可以编写任何可以用作代码片段2的有效代码片段(在使该语言几乎不可用之后将两个数字加在一起)来破解它。但这不是必须是相同的片断,你原本打算。如果强盗破解了您的答案,他们将在您的答案上留下评论,然后您应对其进行编辑以表明它已被破解。如果您的帖子被破解,则应编辑答案以显示您最初打算的解决方案(代码段2)。这本身不是规则,只是为了保持游戏趣味性的友好建议。你不必。

如果一个星期都没有弄清答案,则可以在第二个片段中进行编辑,并指出您的答案现在是安全的。如果您在一周结束后仍未对其进行编辑,则其他用户仍可以对其进行破解,直到您这样做为止。如果您不显示第二个摘要,则无法为您的答案要求分数,也可以称之为安全。

警察线程的胜者是最短的安全答案,包括两个摘要(以字节为单位),并且经过足够的时间后,才会接受此答案。你不是要透露你的字节数,直到你的答案是安全的,因为字节数无关,你的分数,直到你的答案是安全的。如果有足够的时间过去,并且没有答案,那么赢家将是在最长时间内保持不变的答案。

玩得开心!

规则澄清

  • 第一个代码段必须正确运行而不需要任何输入。它可能会输出您喜欢的任何内容,并且该输出将被忽略-只要在代码段完成后,第二个代码段即可正确运行。

  • 为了使您的答案有效,实际上必须执行第二个代码段。这意味着答案像

    import sys
    sys.exit()
    

    无效,因为它不会破坏语言。它只是退出。同样,进入无限循环也是无效的,因为第二个代码段将永远不会执行。

  • 安全后,您的得分就是两个代码段的字节数。

  • 这可以回溯到“ 请揭示工作答案所需的任何奇怪的情况 ……”。您提交的内容必须包含足够的信息,然后才能显示出来,以便显示出来之后可以重现。这意味着,如果您的答案变得安全,然后您输入:这是我的答案。哦,是的,BTW仅在您在Solaris上运行时有效,笑话就在您身上!您的答案无效,将被删除,不符合获奖资格。

  • 在输出总和后,第二个代码段将允许崩溃-只要输出仍然正确(例如,如果您选择输出到STDERR,然后获得一堆崩溃信息,则此无效)。

  • 提交答案后,您可能无法编辑代码。

  • 您可能不依赖加密,散列函数,CSPRNG等加密功能。

片段以查找完整的提交:


3
对于像C这样的语言应该怎么做?串联仅允许一个“主代码段”,并且任何逻辑都必须在此进行。例如,如果我有int main(){ do_evil_stuff(); }用户代码应该放在哪里?在功能上?在所有陈述之后main
科纳·奥布莱恩

1
第二个代码段可以放在第一个代码段的任何位置吗?
LegionMammal978

1
我对编码一无所知,但是这个挑战看起来很惊人,
Pritt Balagopal

2
我编辑了jimmy23013的精彩片段。随时恢复,但我还是自己使用它来查找提交内容,并认为这可能对其他人有所帮助。
Dom Hastings

2
@DomHastings这非常有帮助!非常感谢您:)
DJMcMayhem

Answers:


2

Gforth 0.7.3(TIO),231字节[SAFE]

这段代码将一些必要的输出方法以及添加和声明函数至关重要的内容重新定义为无用的。祝好运!

: . ;
: dec. ;
: u. ;
: .r ;
: u.r ;
: d. ;
: ud. ;
: d.r ;
: ud.r ;
: emit ;
: type ;
: + postpone 2drop ;
: ; + + + postpone exit reveal postpone [ ;

输入将是从堆栈顶部获取的两个带符号整数作为函数参数。输出到STDOUT。

因此,您应该修复所造成的损坏,并定义一个函数,该函数从堆栈中获取前两个值,并将结果作为整数(而不是浮点数)打印到STDOUT,而没有其他输出(没有尾随空格)。

如果您的目标函数名为,这是一个模板f

解:



我实际上immediate从重新定义的末尾删除了79个字节的关键字;,因此答案必须在开始时包含它。我定义的函数在大多数情况下等效于的内部定义.,但它不会在末尾打印空格,并且首先通过将数字移至浮点堆栈并返回来执行加法。

immediate : f s>f s>f f+ f>d swap over dabs <<# #s rot sign #> (type) #>> 0 0 ;

在线尝试


1
这是一个非常好的答案。以此速度看来,它可能最终将成为唯一的完整答案!
DJMcMayhem

:)我结合了两个不同的障碍。在这一点上,我想知道是否可以只做一个来提高我的分数。但是有可能不止一个原因就是它还没有破裂。
mbomb007 '17

21

Haskell,由Christian Sievers破解

import Prelude(getLine,print)
a=a

完整程序,从stdin读取两个整数(包括负整数)并写入stdout。

我刚刚禁用了Prelude,所以范围几乎没有,然后添加了一个定义。进一步的导入在语法上无效。我给了你getLineprint虽然。


编辑添加我的原始解决方案。Christian的破解方法有所不同,但是利用了相同的基本功能(即使无法直接调用任何内置函数,甚至无法命名所涉及的类型,也可以通过访问具有语法糖的函数来获得惊人的计算量)。

import Prelude(getLine,print)
a=a
(x:l)!0=x
(x:l)!n=l!d[0..n]
d[x,y]=x
d(x:l)=d l
x^y=[x..]!y
x+y=f[0..y](x^y)(-((-x)^(-y)))
f[]x y=y
f _ x y=x
f.g= \x->f(g x)
f&0= \x->x
f&n=f.(f&d[0..n])
x*y=((+x)&y)0
x%[]=x
x%('-':s)= -(x%s)
x%(c:s)=x*10+i c%s
i c=l['1'..c]
l[]=0
l(x:s)=1+l s
main=do
 x<-getLine
 y<-getLine
 print((0%x)+(0%y))

无论如何,这可能不是超级高尔夫,但在这里更容易理解:

import Prelude(getLine,print)
a=a

-- List indexing
(x : _) !! 0 = x
(_ : xs) !! n = xs !! (sndLast [0..n])

-- sndLast [0..n] lets us decrement a positive integer
sndLast [x, _] = x
sndLast (_ : xs) = sndLast xs

-- Pseudo-addition: right-operator must be non-negative
x +~ y = [x..] !! y

-- Generalised addition by sign-flipping if y is negative
x + y = switch [0..y] (x +~ y) (-((-x) +~ (-y)))
  where switch [] _ empty = empty   -- [0..y] is null if y is negative
        switch _ nonempty _ = nonempty

f . g = \x -> f (g x)

-- compose a function with itself N times
composeN f 0 = \x -> x
composeN f n = f . (composeN f (sndLast [0..n]))

-- multiplication is chained addition
x * y = composeN (+x) y 0

strToNat acc [] = acc
strToNat acc ('-' : cs) = -(strToNat acc cs)
strToNat acc (c : cs) = strToNat (acc * 10 + charToDigit c) cs

charToDigit c = length ['1'..c]

length [] = 0
length (_ : xs) = 1 + length xs

main = do
  x <- getLine
  y <- getLine
  print (strToNat 0 x + strToNat 0 y)


17

Python 2中破获

实现加法作为命名函数

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\

在线尝试!

这是做什么的?

为了帮助您,我将解释其作用。此代码将打开源文件,并检查其余代码是否符合以下条件:

  • 不包含字符串 import
  • 仅由字符组成 &)(,.:[]a`cdfijmonrt~

如果任一标准均不通过,则将递归限制设置为1意味着您编写的任何代码都将达到递归限制。

这里没有技巧,我写了一个只使用这些字符且不导入的解决方案,我没有做任何颠覆性的事情,但是我会说我认为这很难破解。

为了节省您的时间,这里列出了一些您无法使用此限制无法完成的有用事情

  • + 好吧,

  • eval/ exec不会让你摆脱困境

  • 数字,它们可能比您认为的有用

  • 字符串文字

  • len

  • =,没有分配变量

  • ><==。。。我无可比拟地离开了你

  • *-/%^|>><< 唯一可用的运营商~&

  • __foo__,则不允许使用任何花哨的双下划线方法。


1
哇,这真是邪恶。真好!
HyperNeutrino

揭开序幕的了不起的答案:)
DJMcMayhem

呵呵,这也许会受到启发,通过哑国王的最潜山我试图在聊天符合规范出一个一次挑战
斯蒂芬

4
认为这是一个有效的破解方法:codegolf.stackexchange.com/a/133209/68942
HyperNeutrino

RE的第一个片段:(This code is not allowed to crash or exit.请参阅聊天以获取讨论)
Stephen

12

Python 2破解

这是此答案的第四次迭代。通过重置递归深度可以破解最后一个答案。

实现加法作为命名函数

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\

在线尝试!

这是做什么的?

为了帮助您,我将解释其作用。此代码将打开源文件,并检查代码的其余部分是否仅由字符组成 &)(,.:[]a`cdfijmonrt~

如果失败,则将递归限制设置为1意味着您编写的任何代码都将达到递归限制。

我也禁用了所有模块,因此您无法导入任何内容。

这里没有技巧,我写了一个只使用这些字符且不导入的解决方案,我没有做任何颠覆性的事情,但是我会说我认为这很难破解。

为了节省您的时间,这里列出了一些您无法使用此限制无法完成的有用事情

  • + 好吧,

  • eval/ exec不会让你摆脱困境

  • 数字,它们可能比您认为的有用

  • 字符串文字

  • len

  • =,没有分配变量

  • ><==。。。我无可比拟地离开了你

  • *-/%^|>><< 唯一可用的运营商~&

  • __foo__,则不允许使用任何花哨的双下划线方法。

我的解决方案

因此,既然xnor以一种对我将非常满意的方式破解了它,我将展示我的解决方案

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

惊奇,惊奇它笨拙的堆。与其分解,不如我要讲解我做这个的过程。

我从一个非常标准的加法算法开始

r,o:(o and f(r^o,r&o<<1))or r

然后我用一个按位伎俩代表^|&~

r,o:(o and f((r|o)&~(r&o),r&o<<1))or r

我使用了另一个按位技巧来摆脱 |

r,o:(o and f(~(~r&~o)&~(r&o),r&o<<1))or r

现在剩下的就是<<,不应该太难了吧?好吧,准备颠簸的旅程。为了替换位移位,我使用了字符串在其二进制表示的末尾附加一个零

r,o:(o and f(~(~r&~o)&~(r&o),int(bin(r&o)[2:]+"0",2)))or r

这有一些问题,但是主要的问题是使用加法,因此我通过使用格式来解决此问题。

r,o:(o and f(~(~r&~o)&~(r&o),int("{}0".format(bin(r&o)[2:]),2)))or r

我们不允许使用bin,因此我使用了字符串格式将其转换为二进制。

r,o:(o and f(~(~r&~o)&~(r&o),int("{0:b}0".format(r&o),2)))or r

由于字符串文字是被禁止的,因此我必须{0:b}0使用反斜杠组成的部分将字符串构建join在一起。

r,o:(o and f(~(~r&~o)&~(r&o),int("".join(["{","0",":","b","}","0"]).format(r&o),2)))or r

空字符串很简单,您可以做

`r`[:0]

零是

`0`

{:}全部被字典抢走。

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],"b",`dict()`[-1],`0`]).format(r&o),2)))or r

b似乎是相当难求,它不符合我们的字符集,因此是我们应该怎么去,有一个对象b在其repr?好吧,这是怎么做的:当您使用repr内置函数时,您会得到类似

<built-in function name>

那就是我们从那里得到我们的东西b

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],`min`[1],`dict()`[-1],`0`]).format(r&o),2)))or r

现在剩下的就是数字,我只需要-1、0、1和2,所以这是我表示它们的方式:

-1 = ~(r&~r)
 0 = r&~r
 1 = []in[[]]
 2 = `~([]in[[]])`[[]in[[]]:]

实际上2可能要短一个字节,因为

```r&~r```.find(`r&~r`)

基于@Blender在评论中的建议,但直到事后我才想到这一点。

所以我们用这些数字代替

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

多数民众赞成在裂缝。


这个片段似乎是错误的。
ATaco

@ATaco我相信这是在聊天中讨论的,并确定这是可以的。
小麦巫师

规则另有明确规定。“此代码不允许崩溃或退出。”
ATaco

@ATaco 这是他说有机会时会更新的消息。
小麦巫师


10

C(gcc) 破解!

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}

在线尝试!

从STDIN输入并输出到STDOUT。

这运行没有错误。哈哈哈,这是很邪恶的。我只在TIO的gcc上进行了测试。通常,您必须在此代码段之后附加您的代码,以使其起作用:)注释是很卑鄙的,不要听它。

经过测试gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)。应该可以在任何Linux系统上使用。

原始解决方案

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}
void __attribute__ ((destructor)) dtor() {
    int a,b,c,d;a=b=c=0;
    struct FILE* z = popen("cat", "r");
#define q(x)for(;(c=getc(z))^32&&c^-1;)x=10*x+c-48;
q(a);q(b);
    char*y=calloc(c=a+b,1);
    for(a=0;c;){y[a++]=(48+(c%10));c=c/10;}
    for(b=0;b<a/2;b++){d=y[b];y[b]=y[a-b-1];y[a-b-1]=d;}
    write(1,y,a);
}

@ LegionMammal978是啊
康纳尔奥布莱恩

2
指定您的平台!
约书亚记

@Joshua我添加了一些信息
Conor O'Brien


好了,__asm__您有很多功能可以选择:)不要以为C和C ++在这里是很好的敌人。
edmz

9

Haskell被Ben破解

main=main--

在线尝试! 这应该是一个完整的程序,从stdin读取两个数字并将总和输出到stdout。

每个完整的程序都通过运行main函数开始,但是在此main调用自身并导致无限循环。更糟糕的是,在注释的--后面直接添加了一行注释,以防止将其更改为例如main2,然后定义该注释以进行求和。


预期解决方案:

main=main--$()
_ --$ _ = do
     x <- readLn
     y <- readLn
     print $ x+y

在线尝试!

--启动行注释,除非它也可以作为运算符的一部分进行解析。(语法高亮显示似乎没有意识到这一事实。)--$是一个有效的中缀运算符,它将main第一个参数作为参数,而将第二个参数作为伪参数()。然后定义为忽略两个参数,而是执行所需的任务。



5
您可以只添加“ where main = ...”
michi7x7

对于仅由于Haskell的惰性评估而起作用的Haskell解决方案,+ 1。
Jules

9

C(Linux上的GCC)(破解)

我们没有使用愚蠢的文件读取沙箱技术,而是通过SECCOMP白名单以正确的方式来做到这一点!

您的任务:使用STDIN的输入并输出到STDOUT来实现加法。

#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <syscall.h>
#include <stdio.h>
void sandbox();
__attribute__ ((constructor(0))) int s() {
    close(0);
    close(1);
    close(2);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
}
int main() {
    sandbox();
    syscall(SYS_exit, EXIT_SUCCESS);
}
void sandbox() {
    // Your code here!
}

在线尝试!

WTF是这个!

为了帮助您完成无法克服的任务,我将解释这段代码的作用。

__attribute__ ((constructor(0)))确保该s功能先运行。该函数关闭STDIN,STDOUT和STDERR的所有打开的文件描述符。然后,该程序将自己限制在严格的SECCOMP白名单中,从而将系统调用限制为以下内容:

read(2)
write(2)
_exit(2)
sigreturn(2)

因此,您无法打开任何新文件(或基本上什么也不能做)。然后,我们进入main并调用您的代码,该代码很好地包装在sandbox函数中。

syscall(SYS_exit, EXIT_SUCCESS);在年底只是为了确保该计划干净地退出-默认情况下GCC将退出exit_group(2)其不被白名单的Seccomp允许。运行代码后,将调用此退出函数。

因此,您没有打开的文件描述符,也无法打开任何新文件。不可能吧?;)



8

x86 16位实模式组装(破解

_main:
    call l
    cli
    hlt
l:  pop si
    xor ax, ax
    mov bp, cs
    mov es, ax
    mov di, 12
    mov [di], si
    mov [di + 2], bp
    pushf
    mov bp, sp
    or word [bp], 256
    popf

如果您知道窍门,那很容易。


1
您如何接受输入?在堆栈上还是在寄存器中?(此外,看起来这应该是16位汇编,但是如果这样,or [bp], 256是无效的。应该是or WORD PTR [bp], 256吗?)
Cody Gray

1
此外,你应该指定哪个你使用的处理器; 这里有很多x86版本和克隆,还有很多未定义的指令。如果我为“晦涩的80186克隆”编写代码,但恰好有一条未定义的指令接受了一些参数,等等……我们也可能需要环境。例如,16位Windows给SS == DS保证了其他系统可能没有。
Orion

1
如果您实际上正在使用仅适用于一种特定模型(或某一特定一代)的技巧,则只需指定哪个处理器。这段代码不是那样的,所以我认为“ x86-16”就足够了。我认为,一般性越好。同意应该指定实模式或保护模式,尽管指令(环0)的存在强烈暗示这不是保护模式。hlt
科迪·格雷

3
@Joshua,如果它不能在每个平台上都运行,我必须至少指定一个可以运行的平台。Your submission must contain enough information before being revealed to be reproducible after being revealed
斯蒂芬,

1
@StepHen:一旦指定了x86-16实模式,破解该语言的解决方案是平台无关的,但是I / O不是平台无关的。破解它的人可以指定他破解的操作系统。我后来添加了_main标签,以便理论上有人可以通过链接到libc来做出几乎不可知的突破。
约书亚记

4

Javascript,破解

这项挑战是在Grant Davis的基础上建立,但可以解决他所想到的解决方案(创建iframe并使用iframe的解决方案window)。该解决方案在chrome的javascript控制台中运行about:blank page,需要两个input()s,将它们加在一起,然后console.log是s。将代码放在以下位置:

d=prompt=console=document;new MutationObserver(s=>s.forEach(e=>{t=e.target;t.parentNode.removeChild(t)})).observe(d,{"childList":d, "subtree":d})

首先,我们揍promptconsole并设置快捷键d。然后,我们创建一个带有回调的突变观察器,该回调将删除每个突变的目标。我们设置那个突变观察者来观察文档,并通知childListsubtree修改。true我们使用快捷方式代替真实值document(而不是文字值)(规范不允许这样做,但chrome允许)。

发布此内容后,我意识到了一个更为优雅的功能。我想要的解决方案仍然有效,但是发布的破解无效:

 h=document.querySelector("html");h.parentNode.removeChild(h);

欢迎光临本站!我很想知道解决方案将是什么:)
DJMcMayhem


4

Perl 5,被Ilmari Karonen破解

$_=<DATA>;
s/[+'{dPz|K.UD!_ iJ;o}e6tjWb7253k@%&Iq4l0AN:?\$8B`Yywn9^pfmZQTF"M#-]//g;
eval;
print@_,$!,pop,shift,<>,eval"@>",$\,@ARGV,eval"@$",$@,eval"@@",$,,eval"@,",$/
__DATA__

输入在的单独行上接收STDIN,输出打印到STDOUT

所有代码都在__DATA__标记之后。它使用与@WheatWizard解决方案类似的方法,其中的原因是解析代码并删除不可用的字符。

已在版本5.8、5.10和5.16上进行了测试,并且不需要命令行标志。

在线尝试!


2
您能否指定输入/输出方法和格式?
Ilmari Karonen

@IlmariKaronen抱歉,它STDIN与chars在单独的行和上STDOUT。我将其添加到主体中。
Dom Hastings

我认为是破裂的
Ilmari Karonen

4

Python 3,由zbw破解

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

所有模块都已删除,这意味着没有可用的内置函数,并且无法执行其他任何操作。输出到STDOUT,从STDIN输入。这是该答案的第二次迭代,它是通过添加break语句而使前一个答案被琐碎的裂纹所破坏的。


我真的很好奇看到此片段在此之后
仍然

好吧,您必须等待7天或等待一次平凡的破解,以先到者为准……
pppery


好吧,好了,这些挑战很难做好
pppery

4

APL(ngn-apl),被ngn破解

与我的同事马歇尔合作制造。

通过左右参数输入+。也就是说,您的目标是在以下代码之后插入代码,以便最后一行读取⎕←3+2并输出5到STDOUT。

+←-←−←⍴←≢←≡←⊥←⊤←⍟←○←⍳←⌹←~←∈←∊←⍷←<←≤←=←≥←>←≠←,←⍪←⌷←⌽←⍉←⊖←{}⋄⍣←∘

在线尝试!

通过设置所有有用的函数来工作,这些函数{}接受一个或两个参数并返回一个空的数字列表。也设置为仅构成功能。


裂纹

+←{⌈/⍋⍺⍵1/0}

⍺⍵1/0 用左参数和右参数复制0和1

 得到将排序的索引(由于所有元素均为零,因此给出0 1 2…(a + b)

⌈/ 最大值(a + b)


ngn / apl包括执行任意JavaScript的功能。我认为这样的解决方案无效,因为那将是禁用JavaScript而不是APL。确实有一种+仅使用纯APL而没有肮脏技巧的有效(尽管晦涩)重置方法。
阿达姆(Adám)'17

3

Python 2破解

这是答案的第二次迭代,它由@HyperNuetrino使用我没有想到的方法破解了一次。我现在对其进行了修补,因此希望剩下的唯一解决方案必须遵守我想要的限制。

实现加法作为命名函数

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\

在线尝试!


我想如果有一个可以做到这一点u,但是如果没有它我会陷入困境。
isaacg '17

@isaacg出于好奇,您想做什么u
小麦巫师

.count。我可以得到一个与所需输出一样长的字符串,但是我没有办法确定其长度。
isaacg '17

__import__('sys').setrecursionlimit(100)...并没有实际修补。我真的不喜欢将其发布到强盗的线程中,感觉就像在作弊。在线尝试
Value Ink


3

Java 8,被@OlivierGrégoire破解

这是我的尝试。几乎是,这个想法只是重载所有可用于输出(并希望反映)的名称空间。输出用于sdout(System.out)。

class java {
    public static void main(String[]s){
       //there is no executable code in snippet one.
       //your code here.
    }
    class Class{}
    class Method{}
    class System{}
    class FileDescriptor{}
    class Logger{}
    class Runtime{}
    class Scanner{}
}

黑名单通常比白名单更糟糕,因此我敢肯定,有人提出我没有考虑的方法只是时间问题。


1
这不是可执行的类...
OlivierGrégoire17年

1
@OlivierGrégoire抱歉,我class String{}在测试后添加,但没有意识到它会被淘汰main(String[] ...)。它现在应该可以工作
法夸德勋爵(Lord Farquaad)'17

1
是的,那样做,谢谢!:)它不会改变我要做的破解,虽然:p
OlivierGrégoire'17

1
破解!我真的很喜欢这个:)
OlivierGrégoire17年

1
我正在查看类似的内容(很抱歉,很难在注释中设置代码格式),但是我认为您的解决方案更加int sum = 0; new Exception("" + sum) { public void printStackTrace() { ClassLoader cl = ClassLoader.getSystemClassLoader(); try { printStackTrace(new PrintStream((PrintStream)cl.loadClass("java.lang.System").getDeclaredField("out").get(null))); } catch (Exception e){} } }.printStackTrace();
简洁

3

cQuents,由Mayube破解

#|1,1:A

这应该相当容易,但是您永远不会知道。

“问题”是C您的代码中没有代码,您遇到了一个错误。

Mayube的解决方案:

#|1,1:A+BC

序列中的每个项目都是第一个输入,第二个则是第三个输入(又名1)

我的解决方案:

#1,1:A+B,C

该序列在第一输入加第二输入与第三输入(1)之间循环。第二项中的第一项是A+B

#1,1:A+B+C-C

类似于Mayube的解决方案-而不是相乘B*C,只是相加C然后相减。

在线尝试!

说明

#|1,1      Append 1 and 1 to the end of the user's input
     :     Set mode to : (sequence 1: if given n, output nth term in sequence; if given no n, output whole sequence)
      A    Each item in the sequence equals the first input

当前,此程序输出1,因为没有用户输入,因此第一个输入是1默认输入(#)中的第一个。


该文档的措词似乎很尴尬,我无法一生都知道它的含义Default input is combined with user input to form the total input, which must align with the expected input (which is based on the highest input requested by the Sequence Definition)
Skidsdev

@Mayube很奇怪,我需要找到一种正确地说出它的方法。基本上,您对程序的输入可以等于A,B,C,D,E代码中变量查询的最高输入。例如,如果在程序中的任何时候都有变量D,则解析器期望有4个输入,但是如果还有一个E,则解析器期望有5个输入。不能少于预期的数量。但是,总会有一个可选的最后一个输入,n不同的模式以不同的方式使用它。
斯蒂芬,

我上面发布的代码段@Mayube包含一个A,因此它寻找一个输入。由于有两个,两者均来自#指定默认输入,因此它将第一个用作A值,第二个使用n
斯蒂芬,

因此,如果我要提供2个输入,然后追加BC,则A将是第一个输入,B将是第二个输入,C将是1,而n将是第二个1?
Skidsdev

@Mayube确切地说,对不起我的烂文档。TMI:如果开头看起来像#1,1(无小节),则将是:A作为第一个输入,B作为第二个输入1,C作为第一个输入,而n作为第二个输入。您也可以这样做#1|1,其中A是第一个输入,B是第一个输入,C是第二个输入,n是第二个输入
Stephen

3

Node.JS版本7.3.0(由Dom Hastings破解)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();

将第二个代码块放在第一个之后。

免责声明:第二个代码块将无法单独运行(没有放置在第一个代码块之后)。如果不允许这样做,我可以修改第二个片段。

这是一个完整程序。输出是process.stdout(STDOUT),输入是process.argv(命令行参数)

这是我的第一个警察和强盗,希望这是一个很好的挑战:)

在线尝试!


挑战解释

生成一个n从0到1e7 的随机变量。如果使用正确的调用write n,则不会打印任何内容,而是将l其设置为0会“解锁”写入功能,从而允许您打印任何内容。如果尝试使用非字符串调用write,则会使您陷入无限循环。如果n在写入被“锁定”时尝试使用除正确以外的任何方式来调用写入,则会使您进入无限循环以防止猜测。

预期的解决方案

跳过似乎仅通过使用Symbol(也以s开头)来检查字符串的typeof。由于无法将字符串“ f”添加到Symbol,因此eval调用会在函数中引发错误。我们捕获该错误,并使用正则表达式n从函数名称中的堆栈跟踪中恢复。然后,我们尝试编写n不打印任何内容,而是将“ lock”变量设置l为0以“解锁”写入功能的方法。现在,写入功能已解锁,我们只需打印总和即可。

try{f(Symbol())}catch(e){f(e.stack.match(/f(\d+)/)[1])
f(+p.argv[2]+ +p.argv[3]+"")}


那真是天才……那时候我本来就走对了!感谢您的大脑训练!
Dom Hastings

3

RProgN2,由阿诺德·帕尔默Arnold Palmer)破解

"+-/*÷^"{²[[\=};

覆盖所有数学运算符,无法还原它们。特别是,它用删除堆栈中最上面两个项目的函数来代替它们。

在线尝试!

原始解决方案

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=
{     }`d=                                  #Define a function, "d", which returns n-1
 S                                          #Convert the input to a stack, which, as a number, makes a stack of 1 - n.
  ]‘                                        #Duplicate the stack, and pop the top value off it.
    [                                       #Discard the popped'd value.
     L                                      #Get the length of the stack, which now is n-1.
          {   }`i=                          #Define a function, "i", which returns n+1
           0R                               #Get the range of numbers between 0 and n.
             L                              #Get the length of that stack, which is n+1
                  «                    »`+= #Define a function, "+", which takes two numbers, and outputs their sum. We use «» here, because it localises references, instead of globalising them.
                   x=                       #Set the first input to the value of "x", which by default, is x.
                     y=                     #Ditto for y.
                       x{          x}:      #While x is truthy, which in this case, is non-zero.
                         xd                 #Get x - 1
                           `x=              #Set x to it.
                              yi`y=         #And set y to y + 1
                                      y     #Push y to the output. And we're done.

在线尝试!


我正在阅读您的文档,但似乎找不到该²符号的作用。想启发我吗?
阿诺德·帕尔默

该文档与RProgN2并不十分相关,[[在这种情况下,该符号采用下面的两个概念,并将它们包装在一个函数中@ArnoldPalmer
ATaco


ang,好多了 我不知道堆栈运算符,这肯定会派上用场。另外,了解«»会创建局部变量,而不是混淆全局变量,这将非常有帮助。
阿诺德·帕默

3

Haskell,161 144字节,由BlackCap 破解

{-#OPTIONS_GHC -fth -w#-}
module M where

输入到STDIN,输出到STDERR。添加到程序的末尾。

编辑:打算编译时没有额外的GHC参数,只有正常的ghc --make prog.hs

再次编辑以减少字节数。

玩得开心!


所以我不能这样做,因为不会调用main函数?main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap'7

@BlackCap否,因为当未提供标志时,GHC希望该main功能位于模块中。Main-main-is
zbw

行不通,但是我还是想分享这个想法
BlackCap

我称它为破解。是我想要的解决方案,打了下来。它在TIO上不起作用,因为包装程序不会将输入发送到编译器。
zbw

如果您发布解决方案,我会标记为已破解。
zbw

3

Mascarpone,被Ilmari Karonen破解

[ Make 'i' and 'z' print 'q' ]$
v ['q.]v* 'i<^
v ['q.]v* 'z<^

[ Disable some standard commands ]$
v[]v*   '1<^
v[]v*   '$<^
v[]v*   '@<^
v[]v*   '{<^
v[]v*   '}<^
v[<:]v* '<<^
v[]v*   'v<^$

输入是stdio上的教堂数字,i用于增量和z零。例如,2 + 3将是:

iiziiiz

尾随换行符时,

输出应为stdout上的数字,其格式应与stdio相同。例如,如果答案为5,则应输出:

iiiiiz

(马斯卡彭没有数字的概念)


预期解决方案:

: '[/''/'i/'./' /':/',/'>/'!/']/* 'i<^
: '[/':/',/'>/'!/']/* 'z<^
: ,>!
'z.

从文档中并不能立即看出来,但是正如@IlmariKaronen在其破解中所述,Mascarpone中的字符串文字实际上是用于推送一系列字符的语法糖。

我特意写了一些评论[this]$,以使它看起来像我在推一个字符串,然后立即弹出它。天真的破解者可能曾尝试过[:,>!]/*将字符串推入,与解释器交换并解释的操作。

我还假装用弹出我留在堆栈上的解释器$,但是$已经被重新定义为NOP了。您需要将此解释器放在堆栈中,并且必须随身携带整个程序。通过每个字符串的每个字符。


破解 而且,在挑战之前,我从未听说过Mascarpone。
Ilmari Karonen

@IlmariKaronen新喜欢的语言?做得好!
BlackCap'7

2

C#(.NET Core)被Ilmari Karonen 破解

也被约书亚破解了。

namespace System
{
    class Console
    {
        static void Main()
        {
            //Your code goes here
        }
    }
}

从stdin读取两个值,并将结果写入stdout。在带有Framework Version 3,4.6的Windows和TIO上进行了测试

这是我想要的完整程序。

namespace System
{
    class Console
    {
        static void Main()
        {
            var t = Reflection.Assembly.Load("mscorlib").GetType("System.Console");
            var r = t.GetMethod("ReadLine");
            int a = int.Parse((string)r.Invoke(null, null));
            int b = int.Parse((string)r.Invoke(null, null));
            var w = t.GetMethod("WriteLine", new[] { typeof(int) });
            w.Invoke(null, new object[] { a + b });
        }
    }
}

在线尝试!



codegolf.stackexchange.com/a/133412/14306我认为这不是预期的解决方案。
约书亚

@IlmariKaronen:+1。这是预期的解决方案。
raznagul

@Joshua:+1查找与我预期不同的解决方案。
raznagul

2

GolfScript由丹尼斯破解

{}' !$%&()*+,-./<=>?@[\]^`|~'':'*~;

在线尝试!

毕竟,这挑战,所以为什么不尝试GolfScript?

一个有效的解决方案应该是一个片段,该片段从堆栈中读取两个整数,将它们加在一起,然后在堆栈上返回结果。需要注意的是,即使上面的代码重新定义了几乎所有内置的GolfScript运算符,但实际上仍然无济于事,它仍然应该可以工作。至少我;没有动过,所以您仍然可以将值弹出堆栈。;-)您的代码应在标准的GolfScript解释器上运行,例如在TIO上实现的(请参见上面的链接)。


丹尼斯的解决方案,就像我自己的解决方案一样,依赖于GolfScript 很少使用的功能,该功能允许在双引号字符串中插入Ruby代码。我们使用此功能来定义一个新的加法运算符,其作用与内置+运算符完全相同,然后调用它。

(为什么很少使用GolfScript中的Ruby插值功能的原因之一是,尴尬的是,插值的Ruby代码是在解析过程中执行的,其输出由GolfScript解释器缓存。因此,如果您有一个带有插值的Ruby代码的字符串,在一个循环中,代码只会在实际程序启动之前运行一次,此后在每次循环中始终返回相同的值,您可以使用字符串eval推迟解析,以解决此问题,但这会使原本笨拙的语法更加复杂丑陋且冗长,在任何情况下,我都禁用了eval运算符~,但是事实证明,定义新的内置GolfScript运算符 此功能实际上做得很好很干净是一回事。)



破解 终于弄清楚我在做什么错。
丹尼斯

@丹尼斯:是的,您这次钉了钉子。FWIW,我想要的解决方案"#{var'_','gpush a+b'.cc2}";_,它的工作原理与您的完全一样,只不过少了几个字节。
Ilmari Karonen

2

Node.js v8.2.0,Dom Hastings破解

let mess = ctx => f => new Proxy (f, {
  has: (t, p) => p in t || p in ctx
, get: (t, p) => {
    let k = p in t? t[p]: ctx[p];

    if (k instanceof Function) return (
      function fetch (_k) {
        return mess (ctx) ( x => ( q => q instanceof Function
                                      ? fetch (q)
                                      : t (q)
                                  ) ( _k(x) )
                          )
      })(k);

    return k;
  }
});

with (mess (global) (x => x)) {
  dot   = f => a => b => f(a(b))
  ap    = f => g => x => f (x) (g (x))
  flip  = f => x => y => f (y) (x)
  Const = a => b => a
  id    = x => x
  num   = n => n (x => x + 1) (0)
  log   = console.log

  let x = flip (Const . id . id)
    , y = flip (Const . id . id . id)
  for (let i = 0; i < process.argv[2]; i++) x = ap (dot) (x)
  for (let i = 0; i < process.argv[3]; i++) y = ap (dot) (y)
  process.argv = [];

  logic = x => y => /* Your code here */;

  log . id . num ( logic (ap (dot) (x))
                         (f => z => (( y(flip (id) . id . flip (dot (id)) (f)) ) (Const (z))) (id) )
                 );
}

您要实现该logic功能。输入是提供的参数(来自stdin),输出是函数返回的任何内容(输出到stdout)。


我的代码教会对输入中的数字进行编码。其余的代码只是在吓you您。
mess函数在实现无点表示法a . b == dot (a) (b))方面有些技巧,我主要将其用于添加. id .到随机位置,它不会执行任何操作,但会使不熟悉函数式编程的人感到困惑。
在将数字传递给logic函数之前,应用于数字的转换是x+1y-1,其总和为0,因此这是添加到晦涩之处的另一个NOP。

预期的解决方案是:

logic = x => y => f => z => x (f) (y (f) (z))


@DomHastings这不是预期的解决方案,但是我要说的是,只要程序无例外地暂停并且不输出其他字符即可,您可以这样做
BlackCap

我刚刚发布了一个替代方案!(不过,您可以在该答案的历史中看到我以前的解决方案!)
Dom Hastings

哇,我的路还很遥远...还是比我第一次作弊的尝试要好!谢谢你的困惑!
Dom Hastings

2

通知7被ppperry破解

For reading a command: rule fails.

[Your code here.]

输入应由玩家输入为交互式命令,例如add 17 to 25sum 17 25。您可以自由选择应输入的命令的确切形式,只要它包含两个数字即可。42应根据命令打印数字的总和(例如)。

当然,挑战是这样做,而整个“读取命令”活动却被无操作所取代。解决这个问题的方法可能有几种,但是至少它需要对语言有一定的了解。我想出的一个其实很简单,如果有些意外的话。

我已经在Ubuntu Linux上的GNOME Inform 7 IDE 版本6L38中测试了我的解决方案。预期的解决方案可以在Glulx和Z机后端上运行,并且也可以在其他最新版本的Inform 7上运行。请注意,上面的代码(没有适当的解决方法)将导致解释器在尝试读取命令时忙于循环。Z机器解释器似乎在这种情况下变得完全无响应,并且无法从IDE中停止,因此我建议使用Glulx进行测试。


破解了,如果您想知道,我在挑战之前从未听说过信息
pppery

2

再次由Sisyphus破解的CPython 3

import sys,os,functools
def p(f,e,a,_=os._exit):
 if e == "c_call":_(1)
sys.setprofile(p)

您可以做任何您想做的事情-只要它不是用C实现的。这意味着不print,不input-所有这些都将上_(1)线并终止。从STDIN输入,并在两条单独的线上输入数字,然后输出到STDOUT。我想知道这将持续多长时间...花了我一段时间,想出了这个禁用技巧之后找到了第二个工作片段。明确指定Cpython以避免基于sys.setprofile的某些替代实现而被破解。


破解 我几乎不知道为什么会这样。
西西弗斯(Sisyphus)

我想我现在可以问:为什么functools
丹尼斯,

@Dennis因为sispyphus发现了漏洞,而不是预期的解决方案
pppery

@Sisyphus您的裂缝已报告为python中的错误
pppery

2

Java 8(破解

第二次尝试。这次我投入了两分钟的测试时间。

static {

    try {

        System.setIn(null);
        System.setOut(null);
        System.setErr(null);

        for (Method m : System.class.getMethods()) {

            m.setAccessible(false);

        }

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                if (p.getName().equals("createSecurityManager")) throw new SecurityException();
                if (p.getActions().startsWith("read")) throw new SecurityException();

            }

        };

        System.setSecurityManager(mngr);

        // Your code goes here.

    } catch (Throwable t) {

    }

}

大多数事情应该涵盖。


1
您可以将它与适当的输入内容一起包含在类中吗?这种微小的更改可能会影响或破坏一个条目,这是一种挑战。我为这个解决方案提供了几种解决方案,但是如果将其简单地封装在类/接口中,则可以大大减少解决方案。此外,读者也可以通过格式化删除所有这些行而对我们来说非常好。
奥利维尔·格雷戈尔

在那里,完全使用您的代码破解了答案。和+1,因为似乎我忘了它。抱歉。
奥利维尔·格雷戈尔

#setAccessible(false)调用不执行任何操作。
涅瓦

1

Python 2 破解

import sys,hashlib
c=open(__file__).read().split()[-1]
if c!='#'and hashlib.sha256(c).hexdigest()!='e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843':sys.exit() #

在线尝试!

首先,我将说这个答案是一个混蛋,旨在作为下限答案。


受到Wheat WizardHyperNeutrino答案的启发。

片段读取源文件,如果最后一个空格分隔的代码块未256位,则拒绝继续e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843

编辑:略作修改以回应此评论。核心问题不会改变,任何破解尝试都不会失效。


1
RE第一片段:This code is not allowed to crash or exit.
Stephen

这是无效的,因为它退出了,这是第一个代码段不允许的。
DJMcMayhem


1

Java 8 @OlivierGrégoire破解

我试图使它尽可能的困难!:)而且,与到目前为止的其他Java答案不同,您必须遵循挑战的确切规则,方法是将其放置在整个代码段之后(因此,不要将代码放入public static void main(String[] args)方法中,而是将其放入方法中)上完全课之后:)祝你好运!

我添加了评论以显示受限制的内容。
受此帖子的启发,该帖子的限制性和美感性与我用于回答该问题的方法相同。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

// Your code goes below:

在这里尝试。(ideone.com而不是TIO,因为它在那里似乎无法工作。.测试已经在Eclipse IDE中完成,但是如果您使用ideone.com,我的预期解决方案也可以工作)



1

果冻:破裂

与Wheat Wizard的出色Python答案相比,这将非常容易,但在这里:P

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø<insert code snippet here>

我的解决方法中的sha256 hexdigest(包括第一个代码片段)是cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a

注意

除了字符串之外,您在代码中可能没有任何换行符,否则此代码甚至都不会运行,这违背了此挑战的目的。

被DJMcMayhem破解

公平地讲,它使用换行符,因此我希望看到不使用换行符的解决方案。

乔纳森·艾伦(Jonathan Allan)的解决方案

它不使用换行符,因此已被破解。:P

我的解决方案是这样的:

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø“print(int(input())+int(input()))”ŒV

第一个代码段仅删除单个字符原子,这意味着Python eval仍然有效:)))


第二个代码段始终附加在第一个代码段的末尾。
斯蒂芬,

@StepHen仅指定:P但我忘了添加注释;那真的很重要。
HyperNeutrino

3
我认为您不能像这样限制强盗。如果您可以使用换行符破解它,那就是有效的破解方法。是否有阻止添加换行符或强制执行第一行的方法?
DJMcMayhem


1
我喜欢你打算的裂缝。很偷偷摸摸。
丹尼斯

1

JavaScript,破解

输入:prompt()两次

输出: console.log()

我的解决方案在jsfiddle中不起作用。使用Google chrome的JS控制台在about:blank页面上工作。

prompt=console=0

我的解决方案:

x=document.createElement("iframe")
x.src="data:text/html,<script>console.log(prompt()-0+(prompt()-0))</script>"
document.body.appendChild(x)

说明:

我通过将它们设置为0来删除了提示和控制台。

在我的解决方案中,我创建了一个iframe,它创建了一个沙箱,并创建了一个窗口的新实例,其中提示符和控制台可以正常工作。



@CRDrost我不相信规范中有原始性测试,并且您不会同时显示两个摘要。
斯蒂芬,

抱歉,您是对的,我读错了。
CR Drost

1

Java,破解

import java.lang.reflect.*;
public class Main{
  public static void main(String... args){
    System.setOut(null);
    System.setErr(null);
    /*Your code here*/
  }
}

应该是很容易破解。

预期的解决方案

import java.lang.reflect.*;
public class Main{
public static void main(String... args){
  System.setOut(null);
  System.setErr(null);
  try{
    Class<?> cistream = Class.forName("java.io.InputStream");
    Class<?> cfostream = Class.forName("java.io.FileOutputStream");
    Class<?> costream = Class.forName("java.io.OutputStream");
    Class<?> cfdescriptor = Class.forName("java.io.FileDescriptor");
    Object sout = cfostream.getConstructor(cfdescriptor).newInstance(cfdescriptor.getField("out").get(null));
    Class<?> csys = Class.forName("java.lang.System");
    Field mod = Field.class.getDeclaredField("modifiers");
    mod.setAccessible(true);
    Field stdout = csys.getField("out");
    mod.set(stdout,Integer.class.cast(mod.get(stdout) )&~ Modifier.FINAL);
    stdout.set(null,Class.forName("java.io.PrintStream").getConstructor(costream).newInstance(sout));
    Class<?> cscanner = Class.forName("java.util.Scanner");
    Object scanner = cscanner.getConstructor(cistream).newInstance(System.in);
    Method nextInt = cscanner.getMethod("nextInt");
    int f = Integer.class.cast(nextInt.invoke(scanner));
    int s = Integer.class.cast(nextInt.invoke(scanner));
    int sum = s + f;
    System.out.println(sum);
  }catch(Throwable t){t.printStackTrace();}
  }
}

在线尝试



我完全忘记了java.io..但是您还是得到了预期的解决方案..
RomanGräf17年

我在这里没有任何问题。我实际上写了第二个片段,只是忘了对其进行编辑。根据TIO的说法,第一个摘要在没有任何警告的情况下进行编译。
罗曼·格拉夫(RomanGräf)

@OlivierGrégoire完成。我认为任何IDE都会为此大吼大叫,但我至少编译器会接受它……
RomanGräf17年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.