Hinterhältiger Wettbewerb: Der OS-Krieg [geschlossen]


29

Wir alle wissen, wie die Diskussion um das beste Betriebssystem viele Flammenkriege ausgelöst hat. Ihr Ziel ist es nun, den entscheidenden "Beweis" zu erbringen, dass Ihr Lieblingsbetriebssystem besser ist ... ah, nein, viel besser, den entscheidenden "Beweis" zu erbringen, dass ein anderes Betriebssystem schlecht ist.

Die Aufgabe: Schreiben Sie ein Programm, das einige Berechnungen durchführt und auf mindestens einem Betriebssystem korrekt und auf mindestens einem anderen falsch funktioniert.

  • Das Programm sollte zumindest einige Berechnungen durchführen, daher muss es einige einfache Eingaben lesen (vorzugsweise auf der Standardeingabe, oder wenn aus Dateien, wenn Sie möchten, aber der Missbrauch von Little Endian / Big Endian wäre nicht nur billig, sondern auch offensichtlich) . und bieten einige Ausgabe abhängig von der Eingabe. Die Berechnungen sollten aussagekräftig und gerechtfertigt sein, beispielsweise um ein reales Leben oder ein mathematisches Problem zu lösen.
  • Sie sollten beide Betriebssysteme angeben und angeben, auf welchem ​​es ordnungsgemäß funktioniert und auf welchem ​​nicht. Beide Betriebssysteme sollten wohlbekannt sein und ungefähr zur gleichen Zeit (also kein DOS 1.0 im Vergleich zu einem modernen Betriebssystem). Es wird empfohlen, in Spoiler-Tags eine kurze Beschreibung der Ursache des Unterschieds anzugeben (insbesondere, wenn Sie den Verdacht haben, dass viele Leute dies nicht bemerken würden).

so was

  • die ursache für den unterschied muss subtil sein, also nein #ifdef _WIN32oder ähnlich, bitte! Denken Sie daran, Ihr Ziel ist es, zu "beweisen", dass dieses spezielle System schlecht ist, sodass die Leute Ihren Trick nicht (sofort) erkennen sollten!

  • Wenn Ihr Code einen sehr seltsamen oder sehr ungewöhnlichen Teil enthält, müssen Sie ihn in Kommentaren begründen, warum er vorhanden ist. Natürlich kann / wird diese "Rechtfertigung" eine große Lüge sein.

Wertung:

Das ist kein Golf! Der Code sollte gut organisiert und einfach gehalten sein. Denken Sie daran, Ihr Ziel ist es, einen Fehler darin zu verstecken, damit die Leute ihn nicht ahnen. Je einfacher der Code, desto weniger verdächtig ist er.

Der Gewinner wird per Abstimmung ermittelt. Die meisten Stimmen nach ungefähr 10 Tagen nach der ersten gültigen Einreichung gewinnen. Im Allgemeinen sollten Antworten, bei denen der Code leicht zu lesen und zu verstehen ist, der Fehler jedoch gut versteckt ist und selbst wenn er entdeckt wird, eher auf einen Fehler als auf Böswilligkeit zurückgeführt werden kann, positiv bewertet werden. Ebenso sollte es viel mehr wert sein, wenn der Fehler nur ein falsches Ergebnis verursacht, anstatt nur das Programm zum Absturz zu bringen oder nichts zu tun.

Wie üblich behalte ich mir das Recht vor, eine Antwort als Gewinner zu wählen, wenn sie nach subjektiven Kriterien nicht mehr als 10% oder 1 Punkt unter derjenigen mit den meisten Stimmen liegt.


5
Interessanterweise make (1)funktioniert das auf praktisch jeder Unix-Box und auf einigen Windows-Boxen nicht richtig. Nicht wegen der Betriebssysteme, sondern wegen der Dateisysteme. Jedes Dateisystem, das das Änderungsdatum von Dateien mit geringer Genauigkeit speichert, makefunktioniert auf einem schnellen Computer möglicherweise nicht ordnungsgemäß.
dmckee

1
@dmckee: deshalb bin ich froh, dass ich nicht alles offen gelassen habe, und du musst einige eingaben einlesen und einige einfache berechnungen machen.
vsz

10
Ich habe es erst jetzt herausgefunden, dass diese Suche nach bösem Code die
ID

3
Wir hoffen auf eine Antwort, die unter Windows und <Linux-Distribution einfügen> funktioniert, aber nicht auf Mac.
Casey Kuball

1
Ich stimme dafür, diese Frage als "Off-Topic" zu schließen, da hinterhältige Herausforderungen auf dieser Site nicht mehr zum Thema gehören. meta.codegolf.stackexchange.com/a/8326/20469
cat

Antworten:


15

Unix-Shell + Standard-Dienstprogramme

Schreiben wir ein Shell-Skript, das den Prozess (im Besitz eines Benutzers) findet, der die meiste CPU-Zeit verbraucht hat, und alle Prozesse mit demselben Namen beendet. Ich nehme an, das gilt als Einlesen von Daten (aus dem System) und Ausführen einer Berechnung. (Dieses Verhalten kann bei Prozessen hilfreich sein, die viele Prozesse blockieren, z. B. Gabelbomben und Google Chrom.)

Das Folgende sollte ein portabler Weg sein, um den Namen des Prozesses mit der größten CPU-Zeit zu ermitteln (ich habe versucht, offensichtliche Linux-Probleme zu vermeiden, habe ihn aber nicht unter Solaris getestet):

ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2

Also unser Drehbuch ist einfach

killall `ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2`

Führen Sie das Programm als root aus, um die besten Ergebnisse zu erzielen, damit Prozesse anderer Benutzer beendet werden können.

Linux und BSD

Dies funktioniert unter Linux und sollte auf den BSDs funktionieren, da killall argdie genannten Prozesse abgebrochen werden arg.

Solaris

Wenn jedoch ein Benutzer unter Solaris ein Programm mit dem Namen 9in einer Endlosschleife ausführt, wird das System durch das Skript heruntergefahren . Das ist weil:

Unter Solaris killall argbedeutet dies , alle Prozesse mit dem Signal abzubrechen arg. So wird die Kommandozeile killall 9. Wie 9die Nummer für SIGKILL unter Solaris führt dies dazu, dass alle Prozesse abgebrochen werden und das System heruntergefahren wird.

NB

Dieses Shell-Injection-Problem tritt unter Linux nicht auf, da der böswillige Benutzer zwar ein spezielles Argument wie -KILLeinen Prozessnamen angeben kann, killall -KILLaber eine Verwendungsmeldung harmlos ausgibt.


3
killallist kein Beispiel. Das sind nur zwei verschiedene Programme mit dem gleichen Namen. Jede Version funktioniert einwandfrei.
dmckee

7
Ja, aber das Shell-Skript funktioniert nicht richtig.
Mechanische Schnecke

12
Haben Sie bemerkt, wie vergleichbar Chrom- und Gabelbomben sind? ;)
kaoD

7
@kaoD: Der Hauptunterschied besteht darin, dass Gabelbomben weniger Speicher benötigen.
Mechanische Schnecke

1
Unter Hinweis darauf , nur , dass es so etwas wie „Google Chromium“ no: Der Google Chrome Browser wird auf dem Open-Source - basierte Chromium - Browser, sondern nur die ehemaligen enthält Google-spezifischen Code und hat die Google-Namen angehängt.
Anko

18

Python

Dieses Programm öffnet das in der Befehlszeile angegebene Bild und zeigt es an.

import Image
import sys

with open(sys.argv[1]) as f:
    im = Image.open(f)
    im.show()

Funktioniert unter Linux, funktioniert nicht unter Windows.

Dies liegt an der Art und Weise, wie Windows Dateien öffnet. Damit dies auf allen Betriebssystemen ordnungsgemäß funktioniert, muss der Binärmodus angegeben werden.


4
Das Programm sollte einige Berechnungen durchführen und die Ergebnisse anzeigen. Auf einem bestimmten Betriebssystem sollten auch einige, aber falsche Ergebnisse angezeigt werden. Ja, mit einigem geschickten Wortspiel könnten Sie argumentieren, dass dies genau das ist, was Ihr Programm tut, aber ich denke, es ist eine absichtliche Fehlinterpretation der Regeln. Letztendlich entscheiden jedoch die Wähler.
vsz

5

Little Endian (Intel x86) gegen Big Endian (IBM Power7)

Jedes Dateiformat, in dem binäre Multibyte-Mengen in Nicht-Host-Reihenfolge vorliegen, kann falsch interpretiert werden. Hier ist eine Funktion, die rohes Audio annimmt, beispielsweise aus einer WAV-Datei (einem Microsoft Little Endian-Dateiformat) extrahiert, die Amplitude halbiert und das gedämpfte Audio ausgibt.

#include <stdio.h>

int main()
{
    short audio;
    while (fread(&audio, sizeof(short), 1, stdin))
    {
        audio >>= 1;
        fwrite(&audio, sizeof(short), 1, stdout);
    }
    return 0;
}

Auf kleinen Endian-Maschinen funktioniert dies hervorragend, aber auf großen Endian-Maschinen ist es eine Katastrophe. Z.B

01001101 11001110 -> CE4D (little endian format)

Rechtsverschiebung auf Little Endian:

00100110 01100111 -> 8726 (correct)

Rechtsverschiebung auf Big Endian:

00100110 11100111 -> E726 (not correct)

Beachten Sie, dass einige der Nybbles korrekt sind! Tatsächlich ist es eine 50: 50-Chance, dass die Ausgabe korrekt ist, abhängig davon, ob das niedrigstwertige Bit des Sound-Samples 0 oder 1 ist!

Wenn Sie also dieses Audio hören, ist es wie eine halbe Amplitude, aber mit einem lauten, hohen Rauschen überlagert. Ziemlich überraschend, wenn Sie nicht darauf vorbereitet sind!


5

AGB

:"-→_[_+_→_]

Auf dem Computer funktioniert es, aber auf meinem TI-84-Rechner nicht. Warum?

Auf dem Taschenrechner läuft RAM über und wird möglicherweise gelöscht, während auf dem Emulator für Windows RAM aufgrund begrenzter Zuweisung nicht vom Emulator überlaufen kann.


Was tut es?
Ilmari Karonen

Die Frage enthält einen Spoiler (gelbes Kästchen), mit dem Sie den Mauszeiger bewegen können, um den verborgenen Text anzuzeigen.
Timtech

4
Ja, aber was macht es, wenn der RAM nicht überläuft? Hat es tatsächlich "einige Berechnungen", wie die Frage fragt, und wenn ja, was?
Ilmari Karonen

@IlmariKaronen Verkettet nur die Zeichenfolgen. (Sie können natürlich angeben)
Timtech

4

C

Diese Lösung für Problem 100 (über die Collatz-Sequenz) wird von UVa Online Judge akzeptiert.

Dieser Code funktioniert jedoch nur bei * nix- Plattformen , da longtype als 64-Bit-Ganzzahl mit Vorzeichen implementiert ist. Unter Windows ruft der Code ein undefiniertes Verhalten auf, da der longTyp als 32-Bit-Ganzzahl mit Vorzeichen implementiert ist, während einer der Zwischenwerte in cyc()function mindestens 32-Bit für die Darstellung benötigt.

#include <stdio.h>

#define swap(a, b, t) t __tmp__ = a; a = b; b = __tmp__;
#define M 1000000

short l[M] = {0, 1};

int cyc(long n) { // HERE
    if (n < M && l[n]) return l[n];
    n = n & 0x1 ? 3 * n + 1 : n >> 1;
    return n < M ? (l[n] = cyc(n)) + 1 : cyc(n) + 1;
}

int max(int a, int b) { return a > b ? a : b; }

int main() {
    #ifndef ONLINE_JUDGE
    // freopen("input.txt", "r", stdin);
    #endif
    int i, j, m;
    while (scanf("%d %d", &i, &j) == 2) {
          printf("%d %d ", i, j);
          if (i > j) { swap(i, j, int); }
          for (m = 0; i <= j; i++)
              m = max(m, cyc(i));
          printf("%d\n", m);
    }

    return 0;
}

Eine andere Möglichkeit, dies weiter inkompatibel zu machen, besteht darin, das Array zu platzieren l einzubauen main()und entsprechende Änderungen an der cyc()Funktion vorzunehmen . Da die ausführbare Datei unter Windows standardmäßig auf die Anforderung eines 2-MB-Stacks eingestellt ist, stürzt das Programm sofort ab.


2

Python

Ich bin auf StackOverflow darauf gestoßen als nach Eingabe-Timeouts gesucht habe.

 import signal 
 TIMEOUT = 5

 def interrupted(signum, frame): 
     print 'interrupted!' 
 signal.signal(signal.SIGALRM, interrupted) 

 def input(): 
     try: 
         print 'You have 5 seconds to type in your stuff...' 
         foo = raw_input() 
         return foo 
     except: 
         return

 signal.alarm(TIMEOUT) 
 s = input()
 signal.alarm(0) 
 print 'You typed', s 

Dies funktioniert nicht für Windows.


Warum funktioniert das nicht in Windows? Schätze ich, dass Windows POSIX-SIGs nicht unterstützt? Dann ist es nur eine Frage der Standardbibliotheken von Python, die Funktionalität für beide Betriebssysteme verfügbar machen. Ich glaube nicht, dass es dem Geist der Herausforderung entspricht (z. B. funktioniert Pythons Gabel aus offensichtlichen Gründen auch nicht), aber das ist Pythons Fehler (plus der Tatsache, dass es interpretiert wird), nicht Windows. ZB: Einschließen conio.hhätte den gleichen Effekt, aber C wird nicht einmal kompiliert.
KaoD

@kaoD: Ehrlich gesagt bin ich mir nicht sicher, warum es auch in Windows nicht funktioniert. Möglicherweise enthält Linux einige Funktionen, die Windows nicht bietet, sodass dies in Linux und nicht in Windows implementiert werden kann.
beary605

Dann ist es das, was ich vermutet habe: Sie verwenden die POSIX-Funktionalität von Python. IMHO passt dies aus dem zuvor genannten Grund nicht als Antwort, aber hey, ich bin nur eine weitere Ameise in der Kolonie;) Was Sie sehen, ist Pythons "Fehler", nicht Windows. Siehe hierzu: docs.python.org/library/signal.html#signal.signal
kaoD

Die Windows-API bietet keinen abbrechbaren Lesevorgang für eine Pipe innerhalb des Threads.
Joshua

0

Linux + Bash + GNU Coreutils

rm --no-preserve-root -R -dir /

Dadurch wird der Stammordner und alles, was in Windows nicht vorhanden ist, gelöscht, auch wenn Sie bash für Windows installieren :)


Dies funktioniert unter Windows jetzt, da in Windows ein Linux-Subsystem eingebaut ist. (Ich glaube, ich werde es nicht versuchen)
Pavel

@Pavel Ziemlich einfach zu öffnen cmd.exeund zu tippen, um rmzu sehen, dass es nicht funktioniert.
MD XF
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.