Concours sournois: La guerre des OS [clôturé]


29

Nous savons tous comment la discussion sur le meilleur système d'exploitation a provoqué de nombreuses guerres de flammes. Votre objectif est maintenant de fournir une "preuve" décisive que votre système d'exploitation préféré est meilleur ... ah, non, beaucoup mieux, de fournir une "preuve" décisive qu'un autre système d'exploitation est mauvais.

La tâche: écrire un programme qui effectue certains calculs et qui fonctionne correctement sur au moins un système d'exploitation et incorrectement sur au moins un autre.

  • le programme devrait faire au moins quelques calculs, donc il doit lire une entrée simple (de préférence sur l'entrée standard, ou si à partir de fichiers si vous le souhaitez, mais une mauvaise utilisation de petit endian / big endian serait non seulement bon marché, mais aussi évidente) , et fournir une sortie en fonction de l'entrée. Les calculs doivent être significatifs et justifiés, par exemple pour résoudre une vie réelle ou un problème mathématique.
  • vous devez spécifier les deux systèmes d'exploitation, en indiquant sur lequel il fonctionnera correctement et sur lequel il ne fonctionnera pas. Les deux systèmes d'exploitation devraient être bien connus et à peu près au même moment (donc pas de DOS 1.0 par rapport à un système d'exploitation moderne). Il est conseillé de fournir une brève description de la cause de la différence (surtout si vous pensez que beaucoup de gens ne s'en rendraient pas compte) dans les balises de spoiler.

comme ça

  • la cause de la différence doit être subtile, donc non #ifdef _WIN32ou similaire, s'il vous plaît! N'oubliez pas que votre objectif est de «prouver» que ce système spécifique est mauvais, afin que les gens ne puissent pas (immédiatement) repérer votre astuce!

  • s'il y a une partie très étrange ou très inhabituelle dans votre code, vous devez la justifier dans les commentaires pourquoi elle est là. Bien sûr, cette "justification" peut / sera un gros mensonge.

Notation:

Ce n'est pas un golf! Le code doit être bien organisé et simple. N'oubliez pas que votre objectif est d'y cacher un bug afin que les gens ne le soupçonnent pas. Plus le code est simple, moins il est suspect.

Le gagnant sera décidé par vote. Le plus grand nombre de votes environ 10 jours après la première soumission valide gagne. Généralement, les réponses où le code est facile à lire et à comprendre, mais le bogue est bien caché, et même s'il est découvert, peut être attribué à une erreur plutôt qu'à de la malveillance, doit être votée. De même, cela devrait valoir beaucoup plus si le bogue provoque juste un résultat incorrect, plutôt que de simplement provoquer le plantage du programme ou de ne rien faire.

Comme d'habitude, je me réserve le droit de choisir une réponse en tant que gagnante si elle n'est pas plus de 10% ou 1 point en dessous de celle avec le plus de votes, sur n'importe quel critère subjectif.


5
Fait intéressant, make (1)fonctionne correctement sur pratiquement toutes les boîtes Unix et incorrectement certaines boîtes Windows. Pas à cause des OS, mais à cause des systèmes de fichiers. Tout système de fichiers qui conserve les dates de modification des fichiers avec une faible précision peut échouer makecorrectement sur une machine rapide.
dmckee

1
@dmckee: c'est pourquoi je suis content de ne pas avoir tout laissé ouvert, et vous devez lire certaines entrées et faire des calculs simples.
vsz

10
Je viens de comprendre que cette quête de code diabolique a l'ID 6666
vsz

3
Voici pour espérer une réponse qui fonctionne sur Windows et <Insérer une distribution Linux>, mais pas sur Mac.
Casey Kuball

1
Je vote pour fermer cette question comme hors sujet car les défis sournois ne sont plus sur le sujet sur ce site. meta.codegolf.stackexchange.com/a/8326/20469
cat

Réponses:


15

Shell Unix + utilitaires standard

Écrivons un script shell qui trouve le processus (appartenant à n'importe quel utilisateur) qui a utilisé le plus de temps CPU, et tue tous les processus avec le même nom. Je suppose que cela compte comme lire des données (du système) et effectuer un calcul. (Ce comportement pourrait être utile pour les processus qui engendrent de nombreux processus, tels que les bombes à fourche et Google Chromium.)

Ce qui suit devrait être un moyen portable pour obtenir le nom du processus avec le plus grand temps CPU (j'ai essayé d'éviter les Linuxismes évidents mais je ne l'ai pas testé sur Solaris):

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

Donc, notre script est tout simplement

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

Exécutez en tant que root pour de meilleurs résultats, afin qu'il puisse tuer les processus des autres utilisateurs.

Linux et BSD

Cela fonctionne sur Linux et devrait fonctionner sur les BSD, car killall argtue les processus nommés arg.

Solaris

Cependant, sous Solaris, si un utilisateur exécute un programme nommé 9dans une boucle infinie, le script fera tomber le système . Ceci est dû au fait:

Sous Solaris, killall argsignifie tuer tous les processus avec le signal arg. Ainsi, la ligne de commande devient killall 9. Comme 9c'est le numéro de SIGKILL sur Solaris , cela va tuer tous les processus et ainsi faire tomber le système.

NB

Ce problème d'injection de shell ne s'applique pas à Linux, car même si l'utilisateur malveillant peut fournir un argument spécial comme -KILLun nom de processus, killall -KILLil imprimera sans danger un message d'utilisation.


3
killalln'est pas un exemple. C'est juste deux programmes différents avec le même nom. Chaque version fonctionne correctement.
dmckee

7
Oui, mais le script shell ne fonctionne pas correctement.
Escargot mécanique

12
Avez-vous remarqué à quel point les bombes au chrome et à fourche sont comparables? ;)
kaoD

7
@kaoD: La principale différence est que les bombes à fourche utilisent moins de mémoire.
Escargot mécanique

1
Tout en notant qu'il n'y a pas une telle chose comme « Google Chrome »: Le Google Chrome navigateur est basé sur l'open source Chrome navigateur, mais seul le premier contient un code Google spécifique et a le nom de Google attaché.
Anko

18

Python

Ce programme ouvre l'image spécifiée sur la ligne de commande et l'affiche.

import Image
import sys

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

Fonctionne sur Linux, ne fonctionne pas sur Windows.

Cela est dû à la façon dont Windows ouvre les fichiers. Le mode binaire doit être spécifié pour que cela fonctionne correctement sur tous les systèmes d'exploitation.


4
Le programme devrait faire quelques calculs et afficher les résultats. Sur un système d'exploitation spécifique, il devrait également afficher des résultats, mais des résultats incorrects. Oui, avec un jeu de mots intelligent, vous pourriez affirmer que c'est exactement ce que fait votre programme, mais je pense que c'est une mauvaise interprétation délibérée des règles. Cependant, en fin de compte, les électeurs décident.
vsz

5

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

Tout format de fichier comportant des quantités binaires multi-octets dans un ordre non hôte risque d'être mal interprété. Voici une fonction qui prend l'audio brut, disons extrait d'un fichier WAV (qui est un petit format de fichier Microsoft endian), divise par deux l'amplitude et produit l'audio atténué.

#include <stdio.h>

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

Dans les petites machines endiennes, cela fonctionne très bien, mais dans les grandes machines endiennes, c'est un désastre. Par exemple

01001101 11001110 -> CE4D (little endian format)

Déplacer à droite sur le petit endian:

00100110 01100111 -> 8726 (correct)

Déplacez à droite sur big endian:

00100110 11100111 -> E726 (not correct)

Notez que certains nybbles sont corrects! En fait, c'est une chance de 50:50 que la sortie soit correcte, selon que le bit le moins significatif de l'échantillon sonore est 0 ou 1!

Donc, lorsque vous écoutez cet audio, c'est comme une demi-amplitude mais avec un peu de bruit aigu et aigu superposé. Assez surprenant si vous n'y êtes pas préparé!


5

GTB

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

Sur l'ordinateur, cela fonctionne, mais pas sur ma calculatrice TI-84. Pourquoi?

Sur la calculatrice, la RAM déborde et est potentiellement effacée, tandis que sur l'émulateur pour Windows, la RAM ne peut pas être dépassée par l'émulateur en raison d'une allocation limitée.


Qu'est ce que ça fait?
Ilmari Karonen le

Il y a un spoiler (boîte jaune) dans la question que vous pouvez survoler pour voir le texte caché.
Timtech

4
Oui, mais que fait la RAM qui ne déborde pas ? Est-ce qu'il "fait des calculs", comme le demande la question, et si oui, quoi?
Ilmari Karonen le

@IlmariKaronen Il concatène simplement les chaînes. (Vous pouvez spécifier, bien sûr)
Timtech

4

C

Cette solution au problème 100 (concernant la séquence Collatz) est acceptée par UVa Online Judge.

Cependant, ce code ne fonctionne correctement que sur la plate-forme * nix car le longtype est implémenté en tant qu'entier signé 64 bits. Sous Windows , le code invoque un comportement indéfini, car le longtype est implémenté en tant qu'entier signé 32 bits, tandis que l'une des valeurs intermédiaires de la cyc()fonction nécessite au moins 32 bits pour représenter.

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

Une autre façon de rendre cela encore plus incompatible est de mettre le tableau à l' lintérieur main()et d'apporter les modifications correspondantes à la cyc()fonction. Étant donné que l'exécutable est configuré pour demander une pile de 2 Mo par défaut sous Windows, le programme se bloque immédiatement.


2

Python

Je suis tombé sur cela sur StackOverflow lors de la recherche de délais d'attente d'entrée.

 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 

Cela ne fonctionne pas pour Windows.


Pourquoi cela ne fonctionne-t-il pas sous Windows? Ai-je raison de penser que c'est parce que Windows ne prend pas en charge les SIG POSIX? Ensuite, c'est juste une question de bibliothèques standard de Python exposant des fonctionnalités aux deux systèmes d'exploitation. Je ne pense pas que cela suive l'esprit du défi (par exemple, le fork de Python ne fonctionnera pas non plus pour des raisons évidentes) mais c'est la faille de Python (plus le fait qu'il est interprété), pas Windows '. Par exemple: notamment conio.haurait le même effet, mais C ne compilera même pas.
kaoD

@kaoD: Honnêtement, je ne sais pas non plus pourquoi cela ne fonctionne pas sous Windows. Peut-être que Linux a des fonctionnalités que Windows n'a pas, donc cela peut être implémenté dans Linux et non dans Windows.
beary605

Ensuite, c'est ce que j'ai deviné: vous utilisez la fonctionnalité POSIX exposée par Python. À mon humble avis, cela ne correspond pas à une réponse pour la raison indiquée précédemment, mais bon, je ne suis qu'une autre fourmi dans la colonie;) Ce que vous voyez est la "faute" de Python, pas Windows. Voir ceci: docs.python.org/library/signal.html#signal.signal
kaoD

L'API Windows ne fournit pas de lecture annulable sur un canal depuis le thread.
Joshua

0

Linux + bash + GNU coreutils

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

Cela effacera le dossier racine et tout ce qui n'existe pas dans Windows, même si vous installez bash pour Windows :)


Cela fonctionne sur Windows maintenant que Windows a un sous-système Linux intégré. (Je pense que je ne vais pas l'essayer)
Pavel

@ Pavel Assez simple à ouvrir cmd.exeet à taper rmpour voir que cela ne fonctionne pas.
MD XF
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.