Mach deine Sprache * meistens * unbrauchbar (Räuber-Thread)

31

Inspiriert von diesem Kommentar ...

Vielen Dank an die Benutzer Step Hen , Wheat-Wizard und Dennis, die mir geholfen haben, die Spezifikation dieser Herausforderung zu konkretisieren, bevor ich sie veröffentlichte!

Das ist der Thread des Räubers! Für den Faden Cops, gehen hier


In dieser Herausforderung müssen Sie Code ausführen, der dafür sorgt, dass Ihre Sprache unsere Kriterien als Programmiersprache nicht mehr erfüllt. In dieser Herausforderung heißt das, es so zu machen, dass die Sprache nicht mehr ...

  • Zahleneingabe und -ausgabe übernehmen

  • Addiere zwei Zahlen

  • Testen Sie, ob eine bestimmte Zahl eine Primzahl ist oder nicht.

Dies ist eine Herausforderung, bei der es zwei unterschiedliche Herausforderungen mit zwei unterschiedlichen Zielen gibt: Die Cops werden versuchen, Code zu schreiben, der die Sprache größtenteils unbrauchbar macht, und die Räuber werden versuchen, die verborgene Problemumgehung zu finden, die es den Cops ermöglicht ihre Sprache wiederzugewinnen.

Die Bullen werden zwei Code-Schnipsel schreiben:

  1. Eine, die ihre Sprache größtenteils unbrauchbar macht, z. B. indem eingebaute Funktionen für Eingabe / Ausgabe und numerische Operationen entfernt werden. Dieser Code darf nicht abstürzen oder beendet werden. Es sollte möglich sein, Code am Ende dieses Snippets hinzuzufügen, und dieser Code wird ausgewertet . Und

  2. Ein Codeausschnitt, der zwei Zahlen als Eingabe verwendet, sie addiert und ihre Summe ausgibt. Dieses Snippet muss auch nach dem Ausführen des ersten Snippets noch ordnungsgemäß funktionieren. Wenn die beiden Ausschnitte miteinander kombiniert werden, müssen sie ein vollständiges Programm bilden, das zwei Zahlen hinzufügt, oder eine Funktion definieren, die zwei Zahlen hinzufügt. Dieses Snippet wird sich wahrscheinlich auf obskures Verhalten stützen und schwer zu finden sein.

Die Bullen wählen auch eine Standardmethode für die Ein- und Ausgabe . Sie müssen jedoch genau angeben, welches Format (Eingabe und Ausgabe) sie verwenden. Damit Sie ihre Antwort knacken können, müssen Sie dasselbe Eingabe- / Ausgabeformat verwenden, oder Ihr Riss zählt nicht.

Eine Antwort der Polizei wird immer enthüllen

  • Der erste Ausschnitt (offensichtlich nicht der zweite).

  • Sprache (einschließlich Nebenversion, da die meisten Einsendungen wahrscheinlich auf seltsamen Randfällen beruhen)

  • IO-Format, einschließlich, ob es sich um eine Funktion oder ein vollständiges Programm handelt. Räuber müssen dasselbe Format verwenden, um ein gültiger Riss zu sein.

  • Irgendwelche seltsamen Randfälle, die erforderlich sind, damit ihre Antwort funktioniert. Läuft beispielsweise nur unter Linux oder erfordert eine Internetverbindung .

Als Räuber müssen Sie sich eines der Vorschläge der Polizei ansehen und versuchen, es zu knacken. Sie können es knacken, indem Sie irgendwelche schreiben gültiges Snippet , das als Snippet 2 funktionieren könnte (indem Sie zwei Zahlen addieren, nachdem die Sprache größtenteils unbrauchbar gemacht wurde). Dies muss nicht dasselbe Snippet sein, das der Cop ursprünglich geschrieben hat. Sobald du eine Antwort geknackt hast, poste deinen Code als Antwort in diesem Thread und poste einen Link zu deiner Antwort als Kommentar zur Antwort des Polizisten. Dann wird dieser Beitrag bearbeitet, um anzuzeigen, dass er geknackt wurde.

Hier ist ein Beispiel. Für das erste Snippet sehen Sie möglicherweise das folgende Python 3-Programm als Antwort der Polizei:

Python 3

print=None

Übernimmt die Eingabe von STDIN und gibt sie an STDOUT aus

Ein gültiges zweites Snippet könnte sein

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Dies ist gültig, da zwei Zahlen als Eingabe und Ausgabe ihrer Summe verwendet werden, auch wenn Sie die beiden Ausschnitte zusammenfügen, z

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Dies ist ein gültiger Riss zu ihrer Antwort.

Wenn die Antwort eines Polizisten eine Woche lang nicht geknackt ist, kann er sie in seinem zweiten Snippet bearbeiten und darauf hinweisen, dass seine Antwort jetzt sicher ist . Sobald es sicherheitshalber bearbeitet wurde, dürfen Sie nicht mehr versuchen, es zu knacken. Wenn sie es nicht als sicher bearbeiten, können Sie weiterhin versuchen, es zu knacken, bis sie es tun.

Der Gewinner des Räuber-Threads ist der Benutzer, der die meisten Antworten geknackt hat, wobei der Tie-Breaker der Zeitpunkt ist, an dem er N- Risse erreicht hat. (Wenn also zwei verschiedene Benutzer zum Beispiel jeweils 5 Risse haben, ist der Benutzer, der den 5. Crack zuerst gepostet hat, der Gewinner.) Nachdem genügend Zeit verstrichen ist, akzeptiere ich die Antwort des Gewinners mit den meisten Stimmen.

Habe Spaß!

Regelklärungen

  • Das erste Snippet muss korrekt ausgeführt werden, ohne dass Eingaben erforderlich sind . Es kann beliebig ausgegeben werden, und diese Ausgabe wird ignoriert. Solange das Snippet fertig ist, wird das zweite Snippet korrekt ausgeführt.

  • Das zweite Snippet muss tatsächlich ausgeführt werden, damit Ihre Antwort gültig ist. Dies bedeutet eine Antwort wie

    import sys
    sys.exit()
    

    ist nicht gültig, weil es die Sprache nicht bricht. Es hört einfach auf.

  • Nachdem Sie sicher sind, ist Ihre Punktzahl die Byteanzahl beider Ausschnitte .

  • Dies geht zurück auf Bitte enthüllen Sie alle seltsamen Randfälle, die erforderlich sind, damit Ihre Antwort funktioniert . Ihre Einreichung muss genügend Informationen enthalten, bevor sie enthüllt wird, damit sie nach der Enthüllung reproduzierbar ist. Dies bedeutet, dass, wenn Ihre Antwort sicher ist, Sie Folgendes bearbeiten: Hier ist meine Antwort. Oh ja, übrigens funktioniert dies nur, wenn Sie es unter Solaris ausführen, Witze über Sie! Ihre Antwort ist ungültig und wird gelöscht und gilt nicht als gewinnberechtigt.

  • Das zweite Snippet kann nach der Ausgabe der Summe abstürzen. Solange die Ausgabe noch korrekt ist (wenn Sie sich beispielsweise für die Ausgabe in STDERR entscheiden und dann eine Reihe von Absturzinformationen erhalten, ist diese ungültig)

Bestenliste

Hier ist eine Liste aller Benutzer mit mindestens einem Riss, sortiert nach Punktzahl und anschließendem Namen (alphabetisch). Wenn Sie einen Crack einreichen, aktualisieren Sie bitte Ihre Punktzahl entsprechend.

#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
DJMcMayhem
quelle

Antworten:

3

Java 8 von Olivier Grégoire

class A {
  public A() {
    String[] args = System.lineSeparator().split(",");
    System.out.print(Integer.parseInt(args[0]) + Integer.parseInt(args[1]));
  }
}

Probieren Sie es online!

Da Olivier ausdrücklich erlaubt Eingabe über Eigenschaften übermittelt VM Argumente gesetzt verwenden, werde ich festlegen , dass die Eingabe in der VM Argument gegeben werden sollte -Dline.separator=X,Y, wo Xund Ydie Zahlen hinzugefügt werden. Das heißt, um beispielsweise die Nummern 17 und 25 hinzuzufügen, sollte das Programm wie folgt aufgerufen werden:

java -Dline.separator=17,25 Main

Ich glaube, das sollte auf jedem System funktionieren, das Java-Programme auf der Kommandozeile ausführen kann. Selbst auf Systemen ohne Befehlszeile kann ein anderer äquivalenter Mechanismus zum Festlegen von Systemeigenschaften verwendet werden, um die Eingabe an die VM zu übergeben.


Ps. Hier ist mein früherer Crack-Versuch, der aufgrund der Verwendung von JVM-spezifischen Funktionen als ungültig eingestuft wurde:

class SecurityManager extends sun.awt.AWTSecurityManager {
  static {
    String[] args = System.getProperty("sun.java.command").split(" ");
    int a = Integer.parseInt(args[args.length-2]);
    int b = Integer.parseInt(args[args.length-1]);
    System.out.println(a+b);
  }
}

Probieren Sie es online!

Dies stellte sich als viel weniger ausführlich heraus als das vorherige . Das Schwierigste war, eine Unterklasse zu finden SecurityManager, die nicht in einem Namespace liegt, der mit " java." beginnt . Ich vermute, dass dies immer noch nicht die beabsichtigte Lösung ist, aber es funktioniert. *

*) Zumindest bei TIO; Die sun.awt.AWTSecurityManagerKlasse und die sun.java.commandEigenschaft scheinen nicht offiziell dokumentiert zu sein und sind möglicherweise nicht auf allen JVMs verfügbar.

Ilmari Karonen
quelle
Gute Arbeit! Ich habe das ausprobiert, konnte aber kein Objekt finden SecurityManager, das im Geltungsbereich liegt ... Sie können System.inan dieser Stelle jedoch auch lesen , da es noch nicht geschlossen ist.
ZBW
Sorry, das ist eine plattformabhängige Antwort auf zweierlei Hinsicht: sowohl sun.awt.SecurityManagerund "sun.awt.command"ist plattformabhängig und ist nicht Teil von Java .
Olivier Grégoire
Ja, geknackt! :) Die beabsichtigte Lösung war das durchzugehen System.getProperties().get("blah")(da ich nur den Zugang blockiert habe System.getProperty, nicht System.getProperties), aber das ist gut genug! Gut gemacht!
Olivier Grégoire
22

C (GCC / Linux) von Sisyphus

Dieses Snippet schließt die bereitgestellte Funktion und startet eine neue (klassische Code-Injection), die selbst neu definiert wird, closesodass anstelle des Schließens von fd der gewünschte Code ausgeführt wird.

}
int close(int x) {
  int a, b;
  scanf("%d %d", &a, &b);
  printf("%d\n", a + b);

  exit(0);
2012rcampion
quelle
20

Python, Weizen Wizard-Lösung hier

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\
:[]                                                      # my code starts here
sys.setrecursionlimit(1000)
print(int(input())+int(input()))

Ich meine, Sie können einfach das Rekursionslimit zurücksetzen und nichts Schlimmes passiert ...

Funktioniert mit TIO

Hinweis

Dies ist meine allererste CnR-Einreichung. Wenn dies gegen Regeln verstößt, sag es mir bitte und ich werde dies löschen.

HyperNeutrino
quelle
4
Ich bin dumm, dass ich das verpasst habe
Weizen-Zauberer
@ WheatWizard :)
HyperNeutrino
@wheatwizard Geben Sie Ihre beabsichtigte Lösung noch nicht bekannt. Ich würde gerne einen besseren Cop mit Ihrer ursprünglichen Lösung finden, der dieses Problem behebt.
DJMcMayhem
@Djmcmayhem Ich werde wahrscheinlich mit einem del sys umbuchen.
Weizen-Assistent
@ WheatWizard Denken Sie daran os.sys, wenn das einen Unterschied macht: P
HyperNeutrino
15

Haskell von Ben

import Prelude(getLine,print)
a=a
[]++s=s
(a:as)++s=a:(as++s)
r""=""
r(c:s)=(r s)++[c]
t(_:r)=r
ts l=l:ts(t l)
x[_](v:_)=v
x(_:r)(_:s)=x r s
d(a:_:_:_:_:_:_:_:_:_:r)=a:d r
(a:_)!!""=a
l!!(n:m)=d(x['0'..n](ts l))!!m
a+b=[[0..]!!a..]!!b
a-b=let n=[0..]!!a;m=[0..]!!b in
    case [n..m] of
      [] ->   x[m..n][0..]
      l  -> -(x l    [0..])
add('-':x)('-':y)= -(r x+r y)
add('-':x)y=r y-r x
add x('-':y)=r x-r y
add x y=x+y
main=do a<-getLine;b<-getLine;print(add a b)

Ich habe immer noch wörtliche Zahlen und Zeichen (ich benutze 0, '0'und '-'), und [a..]und , [a..b]die ist sehr nützlich. Und ich habe unary -, aber ich könnte verzichten.

Ich erstelle neu ++zu implementieren r( reverse) und zu definieren tund tswelche sind tailund tails. x a bGibt das nth-Element von zurück b, wobei ndie Länge aminus eins ist. xkönnte normalerweise definiert werden als snd.last.zip. Die Funktion dnimmt eine Liste und gibt eine Liste mit den Elementen von den Positionen zurück, die ein Vielfaches von zehn sind. l!!sGibt das nth-Element von zurück l, wobei sdie umgekehrte Zeichenfolgendarstellung von ist n. +Gibt als Ganzzahl die Summe zweier natürlicher Zahlen zurück, die ebenfalls -für die Differenz als umgekehrte Zeichenfolgen angegeben werden .addGibt als Ganzzahl die Summe zweier möglicherweise negativer Ganzzahlen zurück, die als Zeichenfolgen angegeben werden.

Ich frage mich, ob dies etwas ähnlich ist, was Ben im Sinn hatte.

Christian Sievers
quelle
Ja, so ziemlich die gleichen Ideen. Musterabgleich mit Literalen, um Gleichheitstests und Verzweigungen zu erhalten, Aufzählungssyntax, um eine Art Inkrement zu erhalten. Ich war ziemlich überrascht, :als ich feststellte, dass es sogar mit NoImplicitPreludeund ohne Import von etwas im Umfang war .
Ben
7

C (gcc) von Conor O'Brien


void post_main() __attribute__ ((destructor));

void post_main()
{
    int a, b;
    char sum[11];
    void *stdin = fdopen(0, "r");

    fscanf(stdin, "%u %u", &a, &b);
    sprintf(sum, "%u", a + b);
    write(1, sum, strlen(sum));
}

Probieren Sie es online!

Dennis
quelle
ugggg Ich habe vergessen, fscanf und viele dieser anderen Funktionen zu verbieten>.> gute Arbeit
Conor O'Brien
7

Python 2 von Wheat Wizard (vierte Iteration)

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\
c,d:(`int([]in[])`[:[]in[]]).join([((c)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),c)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),((d)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),d)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),`(int([]in[]))`]).rfind(`(int([]in[]))`)

Probieren Sie es online!

Keine Exploits, nur eine Funktion ' &)(,.:[]a`cdfijmonrt~', die wie vorgesehen nur mit Zeichen hinzugefügt werden kann (eigentlich nur'(),.:[]`acdfijmnort' ).

Ich machte keinen Versuch, es kurz zu machen; Ich habe gerade Unterausdrücke für Zwischenwerte wie 0 und die leere Zeichenfolge geschrieben und diese durch Zeichenfolgen ersetzt.

def f(c,d):
	FALSE = []in[]
	TRUE = []in[[]]
	ZERO = int([]in[])
	ONE = int(TRUE)
	EMPTY = `int([]in[])`[:[]in[]]
	ZERO_STR = `ZERO`
	ONE_STR = `ONE`

	ZERO_DICT = dict([(ZERO,ZERO)])
	ZERO_DICT_STR = `ZERO_DICT`

	OPEN_BRACE = ZERO_DICT_STR[ZERO]
	COLON = ZERO_DICT_STR[ONE:][ONE]
	CLOSE_BRACE = ZERO_DICT_STR[ONE:][ONE:][ONE:][ONE:][ONE]

	C_STR = `c`
	D_STR = `d`

	FORMAT_STR_C = ''.join([OPEN_BRACE, ZERO_STR, COLON, C_STR, CLOSE_BRACE])
	FORMAT_STR_D = ''.join([OPEN_BRACE, ZERO_STR, COLON, D_STR, CLOSE_BRACE])

	LENGTH_C_STR = c and FORMAT_STR_C.format(ONE_STR) or EMPTY
	LENGTH_D_STR = d and FORMAT_STR_D.format(ONE_STR) or EMPTY

	TOTAL_STR = EMPTY.join([LENGTH_C_STR, LENGTH_D_STR, ZERO_STR])
	RESULT = TOTAL_STR.find(ZERO_STR)

	return RESULT

Probieren Sie es online!

Die Kernidee ist, dass das Zeichenkettenformat '{0:5}'.format('1')die Zahl Null auf eine Länge von 5ähnlich auffüllt '1 '. Bei der Verkettung zweier solcher Zeichenfolgen ''.joinergibt sich aus der Summe ihrer Länge die Summe der eingegebenen Zahlen. Dann wenden wir uns 0dem Ende zu und rufen .find()die endgültige Position auf, die die Summe ist.

Die '{0:5}'zu formatierende Zeichenfolge wird durch Extrahieren der {:}Zeichen aus Zeichenfolgenrepräsentanten von Wörterbüchern erzeugt, die mit erstellt wurden dict. Die Zeichenfolge jedes aufeinanderfolgenden Summanden wird dort platziert, wo die 5 wäre. Ich wollte ein Diktat wie es {0:5}selbst verwenden, aber sein Repräsentant enthält ein Leerzeichen, das es durcheinandergebracht hat.

Eingaben von 0 bringen den Prozess durcheinander, weil das String-Sub eine Mindestlänge von 1 hat. and/orIn diesem Fall haben wir die mit einem , um den leeren String zu geben.

xnor
quelle
1
Das ist ganz anders als das, was ich beabsichtigt hatte, ich würde gerne eine Erklärung sehen.
Weizen-Assistent
Sie können ganz int([]in[])einfach Golf spielen , int()da beide 0 ausgeben.
Value Ink
5

x86-16-Bit-Real-Mode-Assembly von Joshua

    int  0x3                  ; <---  this is the "robber" portion

    ; -- begin code to print numbers in real-mode asm using ROM BIOS video interrupts --
    add  dx, cx               ; add input values together
    mov  ax, dx               ; move result into AX
    push WORD 0xB800
    pop  ds                   ; DS == starting address of text-mode video buffer
    xor  cx, cx               ; digit counter
    xor  di, di               ; position counter
    mov  bx, 0xA              ; divisor

    test ax, ax               ; is number negative?
    jns  .GetDigits
    neg  ax                   ; convert negative number to positive
    mov  WORD ds:[di], 0x4F2D ; output leading negative sign, in white-on-red
    add  di, 2                ; increment position counter

.GetDigits:
    xor  dx, dx
    div  bx                   ; divide DX:AX by 10 (AX == quotient, DX == remainder)
    push dx                   ; push digit onto stack
    inc  cx                   ; increment digit counter
    test ax, ax
    jnz  .GetDigits           ; keep looping until we've got 'em all

.PrintDigits:
    pop  dx                   ; get digit off of stack
    dec  cx                   ; decrement digit counter
    mov  dh, 0x4F             ; high byte: color attribute (white-on-red)
    add  dl, 0x30             ; low  byte: convert to ASCII
    mov  WORD ds:[di], dx     ; output digit
    add  di, 2                ; increment position counter
    test cx, cx
    jnz  .PrintDigits         ; keep looping until we've printed 'em all

    cli
    hlt

Screenshot des Debug-Dumps des Codes zusammen mit der Ausgabe in der oberen linken Ecke

Erläuterung:

Der durch Joshuas Code eingeführte "Bruch" ist das Setzen des Trap-Flags (TF), das die CPU in den Einzelschrittmodus versetzt. Dies bedeutet, dass immer nur eine Anweisung ausgeführt wird, bevor die CPU mit einem Typ-1-Interrupt stoppt (Traps). Auf diese Weise können Debugger Code in einem Schritt implementieren - sehr praktisch, aber eine echte PITA, wenn Sie den Code außerhalb des Kontexts eines Debuggers ausführen möchten!

Der folgende Codeabschnitt aktiviert das Trap-Flag:

pushf               ; push the FLAGS register onto the top of the stack
mov bp, sp          ; load the pointer to the top of the stack into BP
or word [bp], 256   ; bitwise-OR the WORD at the top of the stack (the copy of FLAGS)
                    ;  with 0x100, which turns on bit 8 (TF)
popf                ; pop the modified flags back off the stack into FLAGS

Durch die Implementierung des Trap-Flags haben wir die Möglichkeit, genau einen Befehl vor den CPU-Traps auszuführen - den, der unmittelbar nach dem POPFhier steht. Also müssen wir diesen einen zählen lassen.

Der Trick ist der INT 3Befehl, der Interrupt Nummer 3 aufruft. Es gibt zwei Gründe, warum dies funktioniert, um den Code "aufzubrechen":

  1. Das Trap-Flag wird in Interrupt-Handlern gelöscht. Dies ist nur ein Teil von Intels Design, wurde aber vermutlich aus Gründen der Vernunft gemacht. Denken Sie daran, dass die Implementierung des Trap-Flags darin besteht, dass nach Ausführung jedes Befehls ein Interrupt vom Typ 1 aufgerufen wird. Wenn also TF nicht gelöscht INT 1würde , würde dies selbst einen Interrupt auslösen - es würde den ganzen Weg nach unten unterbrochen. Außerdem erleichtert das Löschen von TF-Interrupts das Debuggen des Codes, ähnlich wie bei einer IDE, bei der Aufrufe von Bibliotheksfunktionen automatisch übersprungen werden.

  2. Die Art und Weise, wie Interrupts funktionieren, ist im Wesentlichen die gleiche wie bei einer Ferne CALL. Sie rufen den Interrupt-Handler auf, dessen Adresse an der entsprechenden Position in der globalen Interrupt-Vektortabelle gespeichert ist. Da diese Tabelle an der Adresse beginnt 0x0000:0000und in einem 4-Byte- segment:offsetFormat gespeichert ist, ist die Berechnung der Adresse so einfach wie das Multiplizieren von 4 mit dem Interrupt-Vektor / der Interrupt-Nummer. In diesem Fall rufen wir den Interrupt 3 auf, so dass 4 × 3 = 12 wäre.

    … Und Sie werden bemerken, dass Joshua dies sorgfältig für uns eingerichtet hat. Vor dem Aktivieren des Trap-Flags hat er den folgenden Code:

    mov  di, 12
    mov  [di], si
    mov  [di + 2], bp
    

    welches setzt 0x0000:000C(der Interrupthandler für INT 3) auf BP:SI. Das bedeutet, dass es bei jedem INT 3Aufruf das FLAGS-Register auf den Stapel schiebt, gefolgt von der Rücksprungadresse, und dann BP:SIin einem Kontext, in dem das Trap-Flag deaktiviert ist, zu verzweigt , um erneut mit der Ausführung von Code zu beginnen.

Es geht alles bergab nachher INT 3. Alles was wir tun müssen, ist zwei Zahlen zu addieren und das Ergebnis auszudrucken. Abgesehen davon, dass dies in der Assemblersprache nicht so einfach ist wie in anderen Sprachen, wird hier der Großteil des Codes ausgegeben.

Joshua lässt zu, dass der Räuber die gewünschten E / A-Mechanismen angibt. Daher gehe ich vereinfacht davon aus, dass die Werte in DXund übergeben werdenCX Registern werden. Das ist vernünftig, da diese nirgendwo durch seinen "Prolog" -Code überfordert sind.

Die Ausgabe erfolgt dann durch Speichern von ASCII-Bytes direkt im Videospeicher. Der Videopuffer beginnt bei 0xB800:0000CGA, EGA und / oder VGA im Textmodus, sodass wir dort mit dem Drucken beginnen. Das Format lautet: Zeichen im unteren Byte und Farbattribut im oberen Byte. Das bedeutet, dass sich jedes Zeichen auf einem 2-Byte-Versatz befindet. Wir durchlaufen einfach jede der Ziffern in der Zahl (Basis 10), konvertieren sie in ASCII und geben sie einzeln auf dem Bildschirm aus. Ja, das ist viel Code. Es gibt keine Bibliotheksfunktionen, die uns in der Assemblersprache helfen. Dies kann mit ziemlicher Sicherheit weiter optimiert werden, aber ich habe es satt, daran zu arbeiten ...

Nachdem die Ausgabe angezeigt wurde, kann der Code abstürzen oder was auch immer tun, sodass wir nur die Interrupts löschen und die CPU anhalten.

Cody Gray
quelle
Ich bin verwirrt; Ich kann nicht herausfinden, wie dies über den hlt-Befehl bei BP: SP + 1 hinausgeht.
Joshua
@ Joshua Hmm, das ist ein guter Punkt. Darüber habe ich gar nicht nachgedacht. Nachdem ich den Code in Debug durchgegangen bin, führe ich ihn aus INT 3und erhalte sofort wieder die Anweisung, die ihm folgt. Hat das vielleicht etwas mit meiner Testumgebung zu tun? CLIwürde nur Hardware-Interrupts deaktivieren, aber selbst wenn es über das HLThinausgeht, würden Sie denken, es würde durchfallen und den Code lsofort danach ausführen .
Cody Grey
Oh, du warst Single Steping. Ja das würde es tun. Ich werde noch einmal nachsehen, aber ich glaube, ich habe den verdorbenen Code hochgeladen.
Joshua
Ich habe auch ohne Einzelschritt getestet. Kein Unterschied. Dies ist die neueste Version von FreeDOS in VM Virtualbox. Ich habe echte Hardware zur Verfügung, hatte aber keine Lust, sie einzuschalten. @Joshua
Cody Grey
Na klar hast du es dann geknackt. Vielleicht haben Sie einen Weg gefunden, diesen NMI zu erhöhen.
Joshua
4

Python 3 , die 2. Herausforderung von ppperry

Wow, das hat Spaß gemacht! Ich habe es genossen, das zu lösen.

Bearbeiten: OK, ich habe es behoben. Anscheinend befanden sich die Klassen auf TIO an einem anderen Index in der Unterklassenliste als auf meinem Computer. Daher habe ich beide Klassen unterstützt und ein TIO hinzugefügt.

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

# My code begins here
str = "Hello!".__class__
int = (37).__class__
object = str.__base__

def find_subclass(superclass, name):
	for cls in superclass.__subclasses__():
		if cls.__name__ == name:
			return cls

_io_IOBase      = find_subclass(object, '_IOBase')        # <class '_io._IOBase'>
_io_RawIOBase   = find_subclass(_io_IOBase, '_RawIOBase') # <class '_io._RawIOBase'>
_ioFileIO       = find_subclass(_io_RawIOBase, 'FileIO')  # <class '_io.FileIO'>
stdout = _ioFileIO('stdout', mode='w', opener=lambda name,flags: 1) # FD for stdout is 1
stdin  = _ioFileIO('stdin',  mode='r', opener=lambda name,flags: 0) # FD for stdin is 0
nums = str(stdin.read(), encoding='utf-8').split()
stdout.write(str(int(nums[0]) + int(nums[1])).encode('utf-8') + b'\n')
stdout.flush()

Probieren Sie es online!

zbw
quelle
Ich bekomme eine Fehlermeldung. sys.excepthook is missing?
21.
Hmm ... funktioniert bei mir. Was ist der wahre Fehler, den Sie bekommen? (Das passiert, weil der Code von ppperry so ziemlich alles zerstört hat, einschließlich des Wissens, wie man Ausnahmen anzeigt. Das ist also die sys.excepthookUrsache, aber irgendwo dort wird eine wirkliche Ursache aufgeführt.)
zbw
Egal, der wahre Fehler ist IndexError('list index out of range',). Es ist auf der Linie mit der Definition von _io_RawIOBase.
21.
Das Problem ist, dass die Reihenfolge der Unterklassen nicht festgelegt ist. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]sollte überall funktionieren.
Dennis
@ Tennis Yep, das habe ich gemerkt und gerade behoben. Es funktioniert jetzt auf TIO!
zbw
4

Haskell von zbw

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

import Language.Haskell.TH.Syntax
import System.IO.Unsafe

a = $( runIO $ TupE[] <$
              do x <- readLn :: IO Integer
                 y <- readLn
                 print $ x + y )

Kann keinen Code zur Laufzeit ausführen? Führen Sie es zur Kompilierungszeit aus!

Das hat sehr viel Spaß gemacht, ich kannte Template Haskell vor dieser Herausforderung nicht.

BlackCap
quelle
3

Gelee durch Hyperneutrino


+

Super einfach. Die Newline bewirkt, dass der erste Link nicht aufgerufen wird.

Probieren Sie es online!

DJMcMayhem
quelle
Sie können auch die No-Newline-Regel wie diese
Jonathan Allan
Ja, ich dachte, das wäre zu einfach.
HyperNeutrino
3

Python 2 von Wheat Wizard

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\
a,b:a+b
__import__('sysconfig').__dict__['os'].__dict__['sys'].setrecursionlimit(1000)
print(f(1,2))

Probieren Sie es online!

Sisyphus
quelle
Dies gestaltet sich schwieriger als ich dachte.
Weizen-Assistent
3

Java von LordFarquaad

Das Sperren des Zugriffs auf die Objekte auf der Quellebene war wirklich klug (und beim Testen ärgerlich), gut gemacht!

public class java {
  public static void main(String[] s) {
    //there is no executable code in snippet one.
    //your code here.
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      Object in = cl.loadClass("java.lang.System").getDeclaredField("in").get(null);
      Object out = cl.loadClass("java.lang.System").getDeclaredField("out").get(null);
      Object scanner = cl.loadClass("java.util.Scanner").getConstructor(cl.loadClass("java.io.InputStream")).newInstance(in);
      int i = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      int j = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      cl.loadClass("java.io.PrintStream").getMethod("println", Object.class).invoke(out, i+j);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  class Class {}
  class Method {}
  class System {}
  class FileDescriptor {}
  class Logger {}
  class Runtime {}
  class Scanner {}
}
Olivier Grégoire
quelle
Nett! Was wäre, wenn ClassLoadersie beschattet worden wären ?
Jakob
1
@ JakobCornell "".getClass().getClassLoader(). Das Abschatten ist normalerweise nur ein Problem, über das Sie einmal nachdenken müssen, und dann ist es in Ordnung. Du könntest sogar Schatten werfen Object, ich wäre immer noch in der Lage, das zu lösen. Ok, Sie könnten mich in die 1kb-Lösung zwingen, aber es ist möglich.
Olivier Grégoire
3

Inform 7 von Ilmari Karonen

Offensichtlicher Missbrauch mehrdeutiger Substantive ... Mein Code beginnt mit factory is a room. Die vorherige Zeile ist der Code des Polizisten. Geben Sie beispielsweise ein add 1 and 1, um 2 zu erhalten.

For reading a command: Rule fails

factory is a room.
The adder one is a thing. The adder two is a thing. The adder one is in factory. The adder two is in factory.
Before reading a command: change the text of the player's command to "examine adder"

For printing a parser error: 
    if the player's command includes "add [number] ":
        let N be the number understood;
        if the player's command includes "and [number]":
            say the number understood plus N;
Pfeffer
quelle
2

Java, Roman Gräf

public class Main {
    public static void main(String... args){
        System.setOut(null);
        System.setErr(null);

        System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
        System.setErr(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));
        System.out.println("This");
        System.err.println("works");
    }
}

Sets stdoutundstderr zurück auf ihre ursprünglichen Werte.

Ich glaube, ich kann den vollqualifizierten Namen anstelle eines Imports verwenden. Wenn ich mich irre, korrigieren Sie mich bitte (dies ist mein erster Beitrag hier). Dies könnte wahrscheinlich auch durch Reflektion geschehen.

Bearbeiten: hier ist eine reflektierende Lösung mit nur java.lang.reflect.*:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test {
    public static void main(String... args) {
        System.setOut(null);
        System.setErr(null);

        try {
            Class<?> psClass = Class.forName("java.io.PrintStream");
            Class<?> fsClass = Class.forName("java.io.FileOutputStream");
            Class<?> osClass = Class.forName("java.io.OutputStream");
            Class<?> fdClass = Class.forName("java.io.FileDescriptor");
            Class<System> sClass = System.class;
            Constructor psCtor = psClass.getConstructor(osClass);
            Constructor fsCtor = fsClass.getConstructor(fdClass);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);

            Object sout = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("out").get(null)));
            Field outField = sClass.getDeclaredField("out");
            modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
            outField.set(null, sout);

            Object serr = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("err").get(null)));
            Field errField = sClass.getDeclaredField("err");
            modifiersField.setInt(errField, outField.getModifiers() & ~Modifier.FINAL);
            errField.set(null, serr);

            System.out.println("This");
            System.err.println("works");
        } catch (Exception ignore) {
        }
    }
}
Moira
quelle
Yep, stdin, stdoutund stderrwerden an anderer Stelle gespeichert! Sie müssen nicht einmal verwenden setOutund setErrda können Sie einfach die PrintStreamdirekt verwenden.
Olivier Grégoire
Es wurde eine reflektierende Lösung hinzugefügt, und ich bin der Meinung, dass dies ursprünglich erwartet wurde
Moira,
2

JavaScript von Daniel Franklin

location="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"

Dies kann als eine etwas betrügerische Lösung angesehen werden, funktioniert jedoch unter Chromium 59 / Linux, auch wenn ich zusätzlich eine Warnung erhalte:

In den kommenden Versionen werden inhaltsinitiierte Top-Frame-Navigationen zu folgenden Daten blockiert: URLs. Weitere Informationen finden Sie unter https://goo.gl/BaZAea .

Ps. Hier ist ein weiterer Riss, diesmal ohne Warnung:

Node.prototype.removeChild=function(){}
document.body.innerHTML='<iframe src="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"/>'
Ilmari Karonen
quelle
Ich denke, prompt()- -prompt()speichert zwei Bytes
Marie
2

Java 8 von Olivier Grégoire

Ein äußerst ausführlicher Riss für eine äußerst ausführliche Herausforderung. :) Der Schmerz, indirekt mit Klassen zu arbeiten, die Sie nicht benennen können, ist spürbar.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class filein  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.io.FileInputStream");

      InputStream cmd = (InputStream) filein.getConstructor(String.class).newInstance("/proc/self/cmdline");
      byte[] buf = new byte[65536];
      int len = cmd.read(buf);
      String[] args = new String(buf, 0, len).split("\0");
      
      int a = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-2]);
      int b = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-1]);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

Probieren Sie es online!

Ps. Hier ist mein früherer Versuch, der geschrieben wurde, bevor Olivier klarstellte, dass die Eingabe über Befehlszeilenargumente erfolgen sollte. Im Gegensatz zum obigen Riss ist dieser nicht Linux-spezifisch.

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class scanner = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.util.Scanner");

      InputStream in = (InputStream) system.getField("in").get(null);
      Object scanIn = scanner.getConstructor(InputStream.class).newInstance(in);

      int a = (int) scanner.getMethod("nextInt").invoke(scanIn);
      int b = (int) scanner.getMethod("nextInt").invoke(scanIn);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

Probieren Sie es online!

Ilmari Karonen
quelle
Wenn Sie dazu bereit sind, ist hier meine neue Herausforderung .
Olivier Grégoire
Nur um es hier zu schreiben: Da ich nicht das Recht habe, "Gotcha! Es funktioniert nur auf einem System" zu sagen, ist diese Antwort der Herausforderung nicht ganz gewachsen, da sie nur unter Linux funktioniert.
Olivier Grégoire
@ OlivierGrégoire: FWIW, ich habe eine alternative Lösung gefunden, String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");die nicht Linux-spezifisch ist, aber eine scheinbar undokumentierte Eigenschaft verwendet, die von einigen JVMs festgelegt wird.
Ilmari Karonen
Das ist immer noch nicht tragbar. Zum Beispiel funktioniert es nicht mit IBM Java. Es ist jedoch eine schöne Idee! :)
Olivier Grégoire
2

C # (.NET Core) von raznagul

Ich gehe davon aus, dass dies nicht die beabsichtigte Lösung war.

int a;
int b;

using (var f = new System.IO.FileStream("/dev/stdin", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var fs = new System.IO.StreamReader(f))
{
a = int.Parse(fs.ReadLine());
b = int.Parse(fs.ReadLine());
}
}
using (var f = new System.IO.FileStream("/dev/stdout", System.IO.FileMode.Open, System.IO.FileAccess.Write))
{
using (var fs = new System.IO.StreamWriter(f))
{
fs.WriteLine((a + b).ToString());
}
}
Joshua
quelle
Netter Trick mit /dev/std*da. Ursprünglich wollte ich einen ähnlichen Ansatz verfolgen, fand aber keinen einfachen Weg, um Streams für stdin / out zu öffnen, ohne auf System.Console zuzugreifen, und entschied mich stattdessen für Reflection. Natürlich funktioniert Ihre Lösung vermutlich nur unter Linux und anderen Unixish-Systemen mit den entsprechenden /devEinträgen, aber raznagul hat nicht ausdrücklich gesagt, dass sie unter Windows funktionieren muss. Und es funktioniert mit TIO.
Ilmari Karonen
@IlmariKaronen: In der Tat; und mein Plan für Windows wäre bei TIO gescheitert.
Joshua
1

Java, von racer290

Dies war eher ein grundlegendes Übersehen, dass staticInitialisierer vor der mainMethode aufgerufen werden. Es war ein schöner Versuch: Ich war throw new Error()am Anfang bestürzt , fand aber am Ende den Weg;)

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException {

    try {

        System.class.getField("in").set(null, null);
        System.class.getField("out").set(null, null);
        System.class.getField("err").set(null, null);

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

        File.class.getField("fs").set(null, null);

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

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                throw new Error("Muahaha!");

            }

            @Override
            public void checkLink(String s) {

                throw new Error("Not this way, my friend!");

            }

        };

        System.setSecurityManager(mngr);

    } catch (Throwable t) {

    }
    // My code here, I guess...
} static {
  java.util.Scanner s = new java.util.Scanner(System.in);
  System.out.println(s.nextInt()+s.nextInt());

    // End of my code
}
Olivier Grégoire
quelle
System.out.println("Hello World!");Addiert nicht zwei Ganzzahlen? .. " 2. Ein Codeausschnitt, der zwei Zahlen als Eingabe verwendet, sie addiert und ihre Summe ausgibt. Dieser Ausschnitt muss auch nach dem Ausführen des ersten Ausschnitts noch ordnungsgemäß funktionieren. Wenn die beiden Ausschnitte vorhanden sind Zusammengenommen müssen sie ein vollständiges Programm bilden, das zwei Zahlen hinzufügt, oder eine Funktion definieren, die zwei Zahlen hinzufügt. Dieses Snippet wird wahrscheinlich auf obskurem Verhalten beruhen und schwer zu finden sein. "
Kevin Cruijssen
@ KevinCruijssen Was kann ich sagen? Wenn die Bullen ihren Job nicht machen, warum soll ich dann ihren machen? : P
Olivier Grégoire
1
@ KevinCruijssen Dort habe ich eine Ergänzung eingefügt.
Olivier Grégoire
@ OlivierGrégoire Der springende Punkt ist, das Hinzufügen von Zahlen zu verhindern, indem die Fähigkeit zur Eingabe, zum Hinzufügen oder zur Ausgabe entfernt wird.
Stephen
@StepHen Ja, danach habe ich es ein bisschen besser verstanden. Überprüfen Sie meine 3 anderen Risse, um zu sehen, dass ich das endlich verstanden habe;)
Olivier Grégoire
1

Java von Kevin Cruijssen

Gut gebaut. Eine Menge Code, mit dem jeder richtig darüber nachdenken kann, wie man diese Herausforderung löst. Ich denke, das "Setzen Sie Ihren Code danach" war ein großer, großer Hinweis.

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);
  }
}

class System {
  static void exit(int n) {}
  static void setSecurityManager(SecurityManager sm) {
    java.util.Scanner scanner =new java.util.Scanner(java.lang.System.in);
    java.lang.System.out.println(scanner.nextInt() + scanner.nextInt());
  }
  static void setIn(Object o) {}
  static void setOut(Object o) {}
  static void setErr(Object o) {}
}

Probieren Sie es hier aus.

Olivier Grégoire
quelle
Das ging schnell .. Das war ja genau meine vorgesehene Lösung! Gut gemacht. :) BEARBEITEN: Ich habe mir die Freiheit genommen, den TIO-Link hinzuzufügen, wenn es Ihnen nichts ausmacht.
Kevin Cruijssen
Nun, ich habe tatsächlich mit der Herausforderung von Racer 290 an dieser Idee gearbeitet, als du deine gepostet hast. Und nein, das macht mir nichts aus.
Olivier Grégoire
1

JavaScript von Grant Davis

document.body.innerHTML='<iframe/>'
w=frames[0]
w.console.log(1*w.prompt()+1*w.prompt())

Funktioniert in der JS-Konsole auf der about:blankSeite (wie im Cop-Post angegeben) unter Chromium 59 / Linux.

Ilmari Karonen
quelle
Das hat nicht lange gedauert. Gut gemacht.
Grant Davis
1

cQuents , Step Hen , 3 Bytes

+BC

Probieren Sie es online!

Ich habe viel mit Step Hen geredet, um herauszufinden, wie zum Teufel seine seltsame Sprache funktioniert, aber kurz gesagt:

Sein Code war #|1,1:A.#|1,1ist die Standardeingabe, dh alle Eingaben an das Programm werden durch 2 Einsen angehängt. (IE, wenn Sie eine 47 und eine 53 übergeben, ist Ihre Eingabe [47, 53, 1, 1].

: stellt einfach den Modus ein, der den ausgibt n dritte Element in der Sequenz wennn ausgibt, eingestellt ist, und gibt ansonsten die gesamte Sequenz aus.

Endlich A bekommt der erste Eingang.

Weil wir 4 Eingänge haben [47, 53, 1, 1], addierenBC zum Ende auch den 2. und 3. Eingang holen, und der 4. Eingang wird implizitn .

Weil unsere Sequenz so ist ABC, wird sie algebraisch analysiert, was bedeutet, dass sie wird A*B*C. Wir wollen das nicht, aber wenn wir ein +zwischen A und B einfügen , wird esA+B*C , wo Aund Bsind unsere Eingaben, und Cist 1.

Skidsdev
quelle
how the hell his weird language worksVielleicht ist es sinnvoller, wenn ich fertig bin
Stephen
@StepHen versteh mich nicht falsch, es ist eine ordentliche Sprache, aber komisch wie die Hölle
Skidsdev
1

C # (.NET Core) von raznagul

var console = typeof(System.ConsoleCancelEventArgs).Assembly.GetType("System.Console");
var readLine = console.GetMethod("ReadLine");
var writeLine = console.GetMethod("WriteLine", new Type[] { typeof(int) });
int a = Int32.Parse((string) readLine.Invoke(null, null));
int b = Int32.Parse((string) readLine.Invoke(null, null));
writeLine.Invoke(null, new object[] {a+b});

Probieren Sie es online!

Dies hätte wahrscheinlich weniger Zeit in Anspruch genommen, wenn ich tatsächlich C # gewusst hätte. Mit einigem Durchsuchen der Dokumentation und ein wenig Hilfe von Jon Skeet gelang es mir jedoch, etwas zusammenzubasteln, das funktioniert.

Ilmari Karonen
quelle
1

Vim Challenge von @DJMcMayhem

Es ist schon eine Weile her, dass ich vim nicht beenden konnte. Hier ist meine Lösung (beachte, dass es weit mehr als 23Bytes ist - es ist also wahrscheinlich nicht die beabsichtigte Lösung):

i
echo "
12
39
"|awk '{s'$(python -c "print(''.join([chr(43),chr(61)]))")'$1} END {print s}'<Esc>vgg!bash

Probieren Sie es online!

Die Idee ist einfach zu Rohr die beiden ganzen Zahlen awküber bash, da =und +waren untauglich ich ein kleines Behelfslösung verwenden musste. Die awkZeile erweitert sich zu:

"|awk '{s'+='} END {print s}

Bearbeiten : Die ursprüngliche Absicht war, dass sich die Eingabe bereits im Puffer befindet, aber das wäre nicht schwieriger - die Hauptschwierigkeit bestand darin, das Hinzufügen zum Laufen zu bringen.

Hier ist der Lösungsvorschlag von @DJMcMayhem: Probieren Sie es online aus!

ბიმო
quelle
Ich denke nicht, dass Sie [insert your number here]im Einfügemodus tun können. Stattdessen ist es einfach schon im Puffer. Aber damit könnte man umgehen Oecho "<esc>Go"|awk..., also denke ich, das zählt. Schön gemacht! Dies ist nicht der Riss, den ich mir vorgestellt habe (ich hatte auf eine reine vim-Antwort gehofft), also werde ich wahrscheinlich eine neue Antwort posten, die externe Befehle und korrigiert !.
DJMcMayhem
1
Hier ist ein Beispiel, das Eingaben auf die richtige Art und Weise vornimmt
DJMcMayhem
Ja, ich war mir bei der Eingabe nicht sicher. Aber die Problemumgehung wäre in der Tat einfach. Ich werde auf offizielle Weise bearbeiten .
19.
Übrigens ist mein gepatchter Ansatz hier oben: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem
1

Java 7 von Poke

  }
  public static void main(java.lang.String[]a) throws Exception {
    int x = Integer.parseInt(a[0]);
    int y = Integer.parseInt(a[1]);
    java.lang.System.out.println(x+y);
  }
}
class String {
}
class System {
  public static java.io.InputStream in = new java.io.ByteArrayInputStream(new byte[0]), out = in, err = in;
  public static void setProperties (Object o) {

Probieren Sie es online!

Es sind keine Linux-spezifischen Tricks erforderlich, nur das einfache Maskieren der nicht qualifizierten Namen Stringund SystemKlassennamen. Dies ist wahrscheinlich nicht die beabsichtigte Lösung, aber es funktioniert.

Ilmari Karonen
quelle
1

RProgN2 von @ATaco

"+-/*÷^"{²[[\=};
{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"={"d"="g"=g~d&gd~&|}"±"={"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"={"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=

Probieren Sie es online!

Dies ist bei weitem nicht die beste Antwort, die ich geben konnte, aber es ermöglicht das erneute Addieren von Zahlen. Hätte ich tatsächlich ein ordentliches Stack-Handling absolviert, hätte ich wahrscheinlich einiges Golf spielen können, aber jetzt bin ich mit der Antwort zufrieden.

In ATacos ursprünglichem Posten ordnete er praktisch alle Hauptrechenoperatoren neu zu, um ihre Eingaben zu zerstören. Um dieses Problem zu beheben, habe ich den Zusatz in Bezug auf seine Binäroperationen neu definiert. Dies war ein Schmerz, da RProgN2 keinen Operator für die binäre Negation oder xor hat.

Hinweis: Wenn Sie die Eingabe testen möchten, müssen Zahlen mit mehr als einer Ziffer im Formular enthalten sein "XX..." n , damit sie in eine tatsächliche Zahl umgewandelt werden können, da RProgN2 jedes Zeichen unverändert akzeptiert, es sei denn, es handelt sich um ein Konzept oder eine Zeichenfolge. Bearbeiten: @ATaco hat festgestellt, dass das Hinzufügen eines '$' vor einer mehrstelligen Zahl dasselbe bewirkt.

EDIT: Hier ist die Logik für meine Lösung. Wie Sie sehen, definitiv nicht der raffinierteste Code, aber es funktioniert.

{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"= # Defines the ~ operator which negates a number
{"D"=                                                                   }     # Remove the top of the stack and assign D with the popped value
     11                                                                       # Push 2 1's to the stack.  The first is used as a counter, the second if the initial truthy value for the loop
       {             }:                                                       # Start a while loop if the top of the stack (popped) is truthy (removes final falsey value)
        ‹                                                                     # Left shift the counter variable
         1D&¬                                                                 # Push negation of last bit of D
             \                                                                # Swap the counter (index 1) and the negated bit (index 0)
              D›]"D"=                                                         # Push D, right shift it, duplicate the value on the stack, then pop and assign the top to D
                       ]1\                                                    # Duplicate the counter, push 1, and swap the counter to the top of the stack
                          2\Š                                                 # Push 2, swap with the counter, then take the log (log_2(counter))
                             1{         };                                    # Run the for loop "for (i=1;i<=log_2(counter);i+=1)"
                               [\                                             # Pop off i, then swap the original counter with the next bit to append
                                 D‹|"D"=                                      # Left shift D, or it with the next bit, then assign D the new value
                                          D¬                                  # Need to check if D was 0 or not (in the case of 0b11...1~)
                                            {                     }{ }?       # Conditional on the truthiness of not D
                                             1"D"=                            # If D was 0, we assign it as 1, then start to bit shift it up
                                                  1\2\Š1{       };            # Same for loop as earlier since the original counter is still on the top of the stack
                                                         [D‹"D"=              # Pop off i, left shift D, then reassign it
                                                                    [         # Else D was non-zero, so just pop off the counter we've been carrying around
                                                                       D      # Push the final value to the top of the stack as a return
                                                                         "~"= # Assign the function between the {}'s to the character '~'

{"d"="g"=g~d&gd~&|}"±"=                                                       # Defines the ± operator which performs a single bit xor
{"d"="g"=         }                                                           # Assign d and g the first and second values on the stack respectively
         g~d&                                                                 # Push ~g&d to the top of the stack
             gd~&                                                             # Push g&~d to the top of the stack
                 |                                                            # Or the top 2 values giving us (~g&d)|(g&~d)
                   "±"=                                                       # Assign this function to the ± operator

{"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"=             # Defines the × operator which performs a full number xor
{"H"="I"=                                                   }                 # Store the top 2 stack values in H and I (in that order)
         11{                            }:                                    # Another while loop with the first one being a counter for later, and the second is our truthy value to start the loop
            ‹H1&I1&±                                                          # Left shift the counter, then push the bit xor of H's and I's lowest bit ((H&1)±(I&1) in infix notation)
                    \                                                         # Swap the calculated bit and the counter
                     H›"H"=I›"I"=                                             # Right shift both variables and store the values back in them
                                 H¬¬I¬¬|                                      # Effectively pushing the value (H!=0 | I != 0)
                                          1\2\Š1{        };                   # Same for loop as the ones above
                                                 [H‹|"H"=                     # Pop off the for loop counter, left shift H, or it with the next bit, and reassign
                                                           H                  # Push the final computed xor value to the top of the stack
                                                             "×"=             # Assign this whole function to the × operator

{"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=                                         # Finally, a function redefining addition as the "+" operator
{"J"="K"=                       }                                             # Store the top 2 stack values in J and K respectively
         1{                }:                                                 # An initial truthy value to start the while loop and the loop itself
           JK&‹                                                               # Push (J&K)<<1 to the stack
               JK×                                                            # Compute the full xor of J and K (J^K in Python)
                  "K"=                                                        # Assign K the value of J xor K
                      ]"J"=                                                   # Duplicate (J&K)<<1 and assign 1 copy to J, leaving (J&K)<<1 as our while check (while ((J&K)<<1))
                             JK|                                              # Finally push the value J|K to the stack to get the addition
                                 "+"=                                         # Assign this function to the "+" operator, restoring it
Arnold Palmer
quelle
Die Bereitstellung einer $ vor einem Stich von Zahlen auch Gruppen es als eine Zahl, zB 56$46$12werden die Nummern 5, 6, 46 und 12 schieben werde ich meine eigentliche Lösung und solche tommorow Post
ATACO
Wusste das nicht. Ich habe irgendwie nur Ihre Callables durchgesehen, um herauszufinden, was die Dinge waren.
Arnold Palmer
Wegen dieser Herausforderung könnte ich tatsächlich eine Dokumentation schreiben.
ATaco
Das wäre wundervoll. Ich habe es geschafft, eine Liste von Befehlen für RProgN zu finden, habe sie aber verloren ... Und es hat nur sehr geholfen, da die Funktionen alle unterschiedlich sind. Ich musste Ihre Funktionen über Ihre alte RProgN-Tutorial-Seite und Ihre aufrufbaren Klassen lernen. Es hat Spaß gemacht, damit herumzuspielen, auch wenn nicht sofort klar war, wie alles funktioniert hat.
Arnold Palmer
1

JavaScript (Node.js) von jrich , 298 Bytes

Ich bin der Meinung, dass dies nicht die beabsichtigte Lösung ist, aber wenn es gut gemacht ist, habe ich eine Weile versucht, herauszufinden, wie man den Namen der deklarierten Funktion erhält! :)

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.stderr.write.call(process.stdout,''+((0|process.argv[2])+(0|process.argv[3])));

Probieren Sie es online!

Dom Hastings
quelle
1
Nicht die beabsichtigte Lösung, aber sehr clever! Schöner Riss +1
jrich
@jrich Ja, ich dachte mir, ich kann das gerne ändern.
Dom Hastings
hoppla ... zu spät! Ich war jedoch mit der Kreativität Ihrer Lösung zufrieden!
Jrich