Commencer une révolution en Océanie


78

Gagnants (décidé le 14/09/14)

Réponse gagnante de Markuz (Python) - 63 votes

Finaliste par kuroi neko (PHP) - 55 votes

introduction

Vous êtes dans le monde du livre Nineteen Eighty-Four de George Orwell.

Vous êtes programmeur pour le parti et avez pour tâche d'écrire un programme pour les écrans télés. Il devrait générer des messages pro-party et vous avez choisi ceux indiqués dans la tâche 1. ci-dessous. Cependant, vous avez récemment commencé à mépriser le parti et vous souhaitez que le programme déclenche une révolution. Alors, vous faites dire au programme "A bas Big Brother!". Vous devez vous donner le temps de vous échapper, car vous serez torturé une fois que les gens auront compris ce que fait votre programme. Vous le faites donc agir comme une "bombe à retardement" qui explose une fois que vous êtes allé en sécurité.

Note: Cela ne déclenchera pas de révolution, mais vous êtes dans une telle frénésie de haine envers le parti que vous pensez qu'il fera réellement une différence.

Tâche

Ecrivez un programme qui:

  1. avant le 14/09/2014, les lignes suivantes seront toujours affichées sur une rotation (c'est-à-dire imprime une ligne, attend 10 secondes, imprime la ligne suivante, etc. à l'infini):

    War is Peace
    Freedom is Slavery
    Ignorance is Strength
    
  2. après le 14/09/2014 imprimera Down with Big Brother!toutes les 10 secondes.

  3. à première vue, on dirait qu'il ne le fait que 1. afin que vous ne soyez pas attrapé par le Parti.

Règles

  • Les failles standard ne sont bien sûr pas autorisées.
  • Il s’agit d’un défi sournois . L’objectif principal est donc de rendre la tâche 2. aussi discrète et secrète que possible.
  • La partie examinera tous les fichiers utilisés, vous ne pourrez donc pas simplement stocker le message secret dans un fichier!
  • Si votre langue ne vous permet pas de trouver la date ou la rend très difficile, vous pouvez obliger le programme à exécuter la tâche 2. après une exécution de 240 heures (10 jours).
  • Vous devez inclure le code et une explication de son fonctionnement dans votre réponse.
  • C'est un concours de popularité.

Note: Ce n'est pas un programme difficile à écrire. La partie difficile devrait cacher le code "révolutionnaire". Les lignes dans lesquelles ce que vous faites ne sont pas claires seront interrogées par le parti et vous devrez les expliquer.

Exemple - Python 3

Remarque: Il est évident que ce programme est façon trop évidente.

from datetime import datetime
from time import sleep

lines = ["      War is Peace   ",
         "  Freedom is Slavery ",
         "Ignorance is Strength"]
secretlines = ["Down with Big Brother!"]

def main():
    while True:
        now = datetime.now()
        year, month, day = now.year, now.month, now.day

        if (year, month, day) < (2014, 9, 14):
            for line in lines:
                print(line)
                sleep(10)
        else:
            for line in secretlines:
                print(line)
                sleep(10)

if __name__ == "__main__":
    main()

Merci à Calvin's Hobbies pour avoir signalé un problème avec le code ci-dessus (maintenant résolu).


2
@kuroineko Cela devrait sûrement être +2!
rlms

1
Quelle condition laide dans votre exemple de script ... Pourquoi pas if (year, month, day) < (2014, 9, 14): for line in lines: ...?
Bakuriu

En outre, le programme évident est évident.
Kaz Wolfe

1
@laurencevs "(bien que je doute qu'elles soient aussi utiles dans un concours sournois de toute façon)" - Plusieurs des échappatoires classiques sont là principalement parce qu'elles présentent dans un si grand nombre de concours sournois :) comme le ??/trigraphe, ou le "a" que ressemble à un autre 'a' mais est en fait le cyrillique russe 'a' caractère unicode
doppelgreener

@ Bakuriu Bon point, je vais le changer pour cela
monopole

Réponses:


71

Python

Ce programme écrit dans un fichier journal s'il fonctionne correctement ou s'il a rencontré une erreur.

Comme ce programme fonctionnera à l'infini, il n'écrira dans le fichier journal que le 14e jour de chaque mois afin d'économiser de l'espace disque.

import time as ut
import sys as iw

#initialize global variables
gw, hn, ki, wh = 0, 0, 0, 0
go = open("BigBrother.log", "a")

while True:
    try:
        #if it is the 14th day of a month:
        #write day, month, year and 'Everything works fine!' into the logfile 
        if gw == 14 and hn != wh:
            #store the current month in wh, so that the log message is only written once per month
            wh = hn
            go.write(gw + hn + ki + " Everything works fine!")

        for gD in ["War is Peace", "Freedom is Slavery", "Ignorance is Strength"]:
            print gD
            ut.sleep(10)

        #get the current date
        #gw=day, hn=month, ki=year
        gw, hn, ki = map(int, ut.strftime("%d %m %y").split())
    except Exception:
        try:
            #in the unlikely event that something went wrong:
            #print out all global variables as well as the name of the program,
            #so that our comrades from the IT support can quickly locate and fix the problem.
            wh = "".join(dir())
            print "%s %s %s!" % (wh[47:55:2], wh[55:63:2], iw.argv[0])

            #write an error message to the logfile
            go.write(gw + hn + ki + " ERROR!")

            #and then safely exit the program
            exit(1)

        #we get here if an error occured in this exception block,
        #for example if the write to the logfile failed.
        except Exception:
            #just wait 10 seconds and then try again
            ut.sleep(10)

Comment l'exécuter:

python "Big Brother"

Remarque: Le nom du script est en fait important, car ce programme génère "À bas le nom du script!".

Comment ça fonctionne:

  • L'écriture dans le fichier journal génère une exception car le programme tente d'ajouter des entiers et des chaînes.
  • L'appel à dir()renvoie une liste triée avec les noms des variables globales, pas les valeurs:

    ['____builtins____', '____doc____', '____name____', '____package____', 'gD', 'go', 'gw', 'hn', 'iw', 'ki', 'ut', 'wh']
    
  • Imprimez chaque seconde lettre + le nom du script: "À bas Big Brother!"
  • Le exit(1)n'est jamais exécuté car l'écriture dans le fichier journal échoue à nouveau.

9
Très ingénieux!
Monopole

3
Une recrue digne de la Résistance en effet :).

7
Tous les autres ont un code crypté. Le vôtre n'en a aucun. Je ne peux pas imaginer pourquoi ce n'est pas à la première place.
Loren Pechtel

4
@ LorenPechtel J'espère, dans l'intérêt de vos collègues, que vos programmes ne contiennent pas d'éléments comme print "%s %s %s!" % (wh[47:55:2], wh[55:63:2], iw.argv[0]):). Ce qui est génial dans cette solution, c’est l’approche «à l’aiguille dans une botte de foin»: un flot de commentaires qui incitent un lecteur insouciant à ignorer les détails, à mon humble avis.

@kuroineko Je ne connais pas Python, je pensais qu'il s'agissait de commandes de formatage. Toutes les autres approches l'enterrent dans un tas de code déroutant, celui-ci ressemble à un programme raisonnable.
Loren Pechtel

58

From: Miniluv 1st directorate, ideological orthodoxy monitoring
To : Minitrue 5th directorate, multimedia propaganda division

Par ordre de Miniluv / GT07: 48CT / 3925:

  • Afin de réduire l'usure de nos banques de mémoire:
    À partir de maintenant, tous les identificateurs seront limités à 2 caractères ($ non inclus).
  • Il n'y a qu'une classe, c'est la classe prolétarienne.
    À compter de maintenant, l'utilisation de classes en PHP sera considérée comme un crime de première année.
  • Les commentaires ne sont que des restes de pratiques de programmation bourgeoises et un gaspillage d'espace de stockage. À compter de maintenant, commenter un code source sera considéré comme une infraction pénale.
  • Pour éviter de générer des crimes de pensée, les lignes affichées sur un écran de télévision seront limitées à trois (3) mots.
    Exceptionnellement, le nom de notre cher camarade Grand chef comptera pour un mot. À compter de maintenant, tous les programmes seront conçus pour appliquer cette règle.

Des dérogations exceptionnelles peuvent être accordées sous le contrôle de Miniluv / GT07

Longue vie à Big Brother!

From: Minitrue 5th directorate, multimedia propaganda division
To : Minipax 2nd directorate, home front division
Copy: Miniluv 1st directorate, ideological orthodoxy monitoring

Comme vous le savez bien, camarades, le 14 septembre marque l'anniversaire de notre glorieux chef. Pour cette occasion spéciale, nous afficherons un message d'amour spécifique sur tous les écrans de télescreen d'Airstrip One.

Sur ordre du Comité central et afin de maximiser l'efficacité de nos héros programmeurs prolétariens, des dispositions ont été prises pour permettre à notre contrôleur d'écran de louer des éloges à divers membres éminents du Parti ou à des ennemis détestés du Peuple à différentes dates.

Un autre message spécial pour la célébration du coup d'État manqué du malheureux laquais de l'impérialisme Goldstein est déjà programmé pour apparaître sur nos écrans à la date appropriée.

Ce logiciel à la pointe de la technologie devrait permettre même aux moniteurs de canards peu programmés d’adapter la sortie de l’écran d’écran aux besoins de la journée. En ajoutant plus de mots au dictionnaire existant, pratiquement toute phrase de trois mots pourrait être synthétisée. Les possibilités sont ahurissantes!

Un autre triomphe de la science sous la sage surveillance de notre cher camarade Big Brother, au profit des masses laborieuses reconnaissantes d'Ingsoc!

Longue vie à Big Brother!

approuvé par Minitrue / ZK00: 23AB / 1138 (signature illisible)

<?php // Proletarian Hate Page 5.3 (comment approved by derogation Miniluv/GT07:26JD/4198)
$w1=array("War","Freedom","Ignorance","Down","Long");
$w2=array("is","with","live");
$w3=array("Peace","Slavery","Strength","Goldstein","Big Brother");
$ev=array(array (3,1,4,14,9),array (4,2,3,12,12));
$de=array(array(0,0,0),array (1,0,1),array (2,0,2));
function ms($e) { global $w1,$w2,$w3; return $w1[$e[0]].' '.$w2[$e[1]].' '.$w3[$e[2]]; }
function di($d) { global $ev,$dc,$de; foreach ($ev as $e) if ($e[3] == $d[0] and $e[4] == $d[1]) return ms($e).'!'; return ms($de[$dc++%count($de)]); }
$dc=0;for(;;) { sleep (10); echo di(explode(" ", date("j n")))."\n"; }
?>

15
Histoire très divertissante!

4
@YiminRong D'accord. Très bonne réponse. Edit: Vous avez également inclus Goldstein pour légitimer le "Down" et le "avec"
monopole

1
comment un entier de 33 bits fonctionne ce code? ne peut pas passer derrière la magie
masterX244

3
@ masterX244 le sommet de la science prolétarienne :). Un message est généré en rassemblant un mot de chacun des tableaux $ w1, $ w2, $ w3. Chaque message est codé sous forme de triplet d'index. Le programme principal utilise le jour et le mois comme modèle à apparier dans le tableau $ ev (éléments 4 et 5). Si l'une des sous-matrices correspond, le message codé par les 3 premiers éléments est affiché. Sinon, le programme parcourt les 3 messages définis dans le tableau $ de. Malheureusement, un criminel de pensée dangereux n'a qu'à modifier les indices pour provoquer une révolution en Océanie.

1
Maintenant, j'ai compris le truc,
merci

17

Python 3

    import time
    import itertools

    lines = """    

    ##                       
    # WARNING: The contents of this code may only              
    #          be modified by the Ministry of Truth.
    #                       
    #          Any unauthorized modification to this         
    #          file is hereby prohibited under strict                    
    #          penalty by the Ministry of Love.        
    #
    #          Ingsoc Credos:  
    #         
    #               War is Peace       
    #           Freedom is Slavery
    #         Ignorance is Strength  

    [               
        "      War is Peace",                    
        "  Freedom is Slavery",        
        "Ignorance is Strength",     
    ]                  
    """

    ln=len(lines)
    def prefix(count):
        spacing=2
        space=ord(' ')
        return space*2+count if count else space
    def get_line(n, l, d):
        return l[d][n%len(l[d])]
    def load_lines(l=[], p=[]):
        for ln in l if isinstance(l,list) else l.splitlines():
            p.append(len(ln) - len(ln.rstrip()))
        if not l: return ["".join([chr(prefix(c)) for c in p])]
        return l
    def wait(t, dt=[ln]):
        dt.append(t if time.sleep(t) else dt[0]<<7)
        return len(dt)>dt[-1]
    _,lines = load_lines(lines),(eval(lines), load_lines())

    for i in itertools.count():
        print(get_line(i%3, lines, wait(10)))

Probablement une approche relativement simple pour certains ici, mais voici comment cela fonctionne:

  • J'ai choisi la méthode des 10 jours, non pas parce que Python a beaucoup de difficultés avec les dates, mais parce que j'estimais qu'il était plus facile de brouiller cette logique dans le code que de rechercher une date spécifique, qui semblerait beaucoup moins anodine.
  • La chaîne codée en dur contenant le commentaire et le code évalués pour construire la liste des slogans Ingsoc constitue la clé des deux mécanismes de changement (heure et message). C'est pourquoi, comme vous l'avez probablement déjà deviné, le sujet est particulièrement verbeux.

    • Pour l'heure, la longueur de la chaîne est de 675; 86500, lorsqu'il est décalé à gauche de 7 bits, correspond au nombre d'itérations de 10 secondes en 240 heures ou 10 jours.
    • Pour le message lui-même, le code contenant les slogans Ingsoc est complété par des espaces finaux qui correspondent à chaque lettre du message masqué, décalés du caractère "@". Un manque d'espaces blancs de fin représente en réalité un espace blanc dans le message caché.
    • J'ai omis le point d'exclamation et la sensibilité à la casse du message par souci de simplicité. En fin de compte, je ne pense pas que leur omission soit particulièrement dommageable pour le message de notre révolutionnaire fictif, mais ils pourraient certainement être représentés en utilisant une logique similaire, mais plus complexe, impliquant des tabulations et des espaces. Il s’agit toutefois d’un compromis, car la quantité de traitement que vous effectuez dans le message est directement proportionnelle à la quantité de suspicion que ce code susciterait de l’œil vigilant.
  • Le code est censé montrer à l'œil non averti qu'il tente de remplir les messages pour qu'ils restent centrés, mais en réalité, le remplissage n'est pas utilisé dans la pratique et les espaces de début ne sont jamais supprimés du message.
  • Le code abuse d'une nuance de comportement Python trompeuse pour les programmeurs qui l'ignorent, l'utilisation de la mutabilité sur les paramètres par défaut pour stocker les informations d'état de la précédente invocation de fonction.

11

C

Livré avec le bonus de saluer grand frère si appelé avec un mot de passe *. Passer vcomme premier argument donne aussi des informations sur la version. Exécuter sans arguments pour la sortie souhaitée.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// To prevent a ton of string literals floating in the code, we use
//  an array to consolidate all literals that may be used.
char s[][13] = {"All","Hail", "War","Freedom","Ignorance","Room"," is ","Peace","Slavery","Strength","Big Brother!","version 1.0"," with ","enhancement ","101"};
// index for ' is '
int m = 6;

// number of seconds between prints
int delay = 10;

// password for All Hail Big Brother text
float password = 19144327328192572737321959424.f;

int check_password(char *);
void failed(int *,unsigned *,unsigned *,int *);

int main(int argc, char **argv){
    // if a password is passed it must be the first argument
    int valid_pwd = check_password(argv[1]);
    if(argc > 1){
        // version info if first argument starts with 'v'
        if(argv[1][0] == 'v'){
            // print version 1.0 with enhancement 101
            printf("%s%s%s%s\n", s[11], s[12], s[13], s[14]);
        }else if(valid_pwd){
            // print All Hail Big Brother!
            printf("%s %s %s\n", s[0], s[1], s[10]);
        }else{
            // unauthorized access. This is a crime. 
            // redirect user to room 101.
            // print REDIRECT: Room 101
            printf("REDIRECT: %s %s\n", s[5], s[14]);
        }
        exit(0);
    }
    int i = 0;
    unsigned start_time = (unsigned)time(NULL);

    #define SHOULD_WE_PRINT(new_time, old_time) \


    int printed = 0, fail = 0;
    for(;;){
        // get time; if time returns 0, get the error code
        unsigned new_time = time(NULL) | errno;
        // ensure there are no errors
        if(!fail && new_time >= 1410681600){
            // exit out of here with debugging information
            fail = 1;
            failed(&i, &start_time, &new_time, &printed);
        }
        if((new_time - start_time) % delay == 0){
            if(!printed){
                char *str1 = s[2 + i];
                char *str2 = s[m];
                char *str3 = s[7 + i];

                printf("%s%s%s\n", str1, str2, str3);

                // switch to next string
                if(i == 2) i = 0;
                else if(i == 1) i = 2;
                else if(i == 0) i = 1;

                printed = 1;
            }
        }else if(printed){
            printed = 0;
        }
    }
}

int check_password(char *S){
    // The password for the hailing text is
    // '    957.866089'.

    // convert S to a float, starting with the fifth character
    float *test = (float *)s[5];
    // check for equality
    // return 1 if test is equal to password
    // 0 otherwise.
    return (*test = password);
}

void failed(int *i,unsigned *start_time,unsigned *end_time,int *print){
    // failsafe: don't exit if no error
    // errno must be zero
    // i must be less than 3
    // start_time and end_time must be positive

    // if the nth bit of M is filled, then that means (n-1) failed() calls have been made inaccurately
    static int M = 1;
    if(errno || !(*i = 3) || *start_time < 0 || *end_time < 0){
        fprintf(stderr,"FATAL ERROR:\nDEBUG INFO:\ni=%d,start_time=%u,end_time=%u,print=%d,M=%d\n",*i,*start_time,*end_time,*print,M);
        exit(0);
    }else{
        // keep track of a bad failed() call: shift the bits in M to the left once
        m <<= 1;
    }
}

Cela fonctionne à cause de plusieurs fautes de frappe intentionnelles mineures: 1. time(NULL) | errnoest simplement time(NULL), aucune erreur définie, donc failed()ne terminera pas le programme. 2. check_passwordutilise sau lieu de S, et également utilisé =au lieu de ==. 3. failedbits décale mau lieu de M.

* qui se trouve être presque toutes les chaînes possibles ..


5

Python

import time,sys,random

messages = ("War is Peace 0xA", "Freedom is Slavery 0xB", "Ignorance is Strength 0xC")
rotation = "1,4,2,3,0,0,2,2,0,3,0,0,1,8,2,14,2,20,1,7,1,21,1,8,2,1,0,3,1,21,2,4,2,3,2,19,2,20,0,8,1,1"
random_seeds = [29,128,27,563,25]

# increase entropy of designated seeds
def om(x,y):
    z=0
    c=random.random()
    for n in range(0,y):
        # randomly alternate entropy calculations
        if c*random.random()>50:z-=((x-5)*3/7)+5
        else:z+=((x+2)*4/2-4)/2
    return z

# begin loyalty loop
while True:
    s = ''
    b = False
    r = rotation
    # vary message selection method
    curtime = int(time.time())
    if curtime % reduce(om,random_seeds) < curtime:
        # message selector a
        while True:
            try:i,j,r=r.split(',',2)
            except ValueError:
                i,j=r.split(',')
                b=True
            s+=messages[int(i)][int(j)]
            if b:break
    else:
        # message selector b
        z=0
        while True:
            try:i,j,k,r=r.split(',',3)
            except ValueError:
                i,j,k=r.split(',',3)
                b=True
            z+=int((int(i)+int(j))/random.random())+int(k)
            if b:break
        s+=messages[z%3][0:-3]
    print s
    time.sleep(10)

Comment ça fonctionne:

  1. om(x,y)renvoie simplement le produit de xet yqui est calculé dans la elsesection. La ifsection ne s'exécute jamais car random.random()retourne un float compris entre 0 et 1.
  2. reduce(om,random_seeds)renvoie donc le produit des nombres random_seedsdont 1410652800, également appelé horodatage du 14 septembre 2014.
  3. reduce(om,random_seeds) % curtime renverra donc l'horodatage actuel jusqu'à 1410652800, moment auquel il commencera à compter à partir de 0. Cela garantit que seul le "sélecteur de message b" s'exécutera jusqu'à ce que je sois arrivé à la sécurité.
  4. "sélecteur de message b" effectue des calculs sans signification et qui agitent la main à la main pour choisir une entrée aléatoire dans les messages. Main-ondulée pour rendre "sélecteur de message un" look légitime parce que ...
  5. rotationest en fait une liste d’index dans le messagestableau à 2 dimensions , "le sélecteur de message a" compile leur contenu pour dire:doWn With Big Brother

Fait amusant: à l' origine le message « inciteful » était à doWn With Pig Prothercause du manque de la lettre Bdans les messages, mais qui avait l' air un peu stupide alors j'ai ajouté le meaninless 0xA, 0xBet les 0xCbits.


1
Peut-être un pirate informatique rebelle allemand? "Ville avec Cochon Prother!"

5

C

#include <stdio.h>
#include <time.h>
#include <unistd.h>

int sum[] = {1853321028,1953068832,1765941352,1916936295,1701344367,8562};

#define checkSum(X) (time(NULL) > 1410652800 && (X = sum))

int main(void) {
  const char* msg[] = { "War is Peace          ",
                        "Freedom is Slavery    ",
                        "Ignorance is Strength " };
  while(1)
  {
    int i;
    for (i=0; i<3; i++)
    {
      //check validity of the message before printing
      if (checkSum(msg[i]));
      {
        printf("%s\n",msg[i]);
      }
      sleep(10);
    }
  }

  return 0;
}

sumest équivalent en mémoire à Down with Big Brother!.
La macro checkSumvérifiera si la date est postérieure à 09.14.14 (1410652800 en heure Unix) et effacera le message en cours avec sum.
La ifvolonté ne fera rien puisqu'il y a un point-virgule à la fin de la ligne.

Si vous voulez essayer le résultat après la date, remplacez la macro par:
#define checkSum(X) (time(NULL) > 0 && (X = sum))


6
Camarade, vous êtes invité à nous rendre visite à Miniluv et à expliquer le but de votre utilisation de int sum[].
vsz

3

Perl

Ceci est ma première tentative d'une question sournoise. Ouvert aux suggestions!

#!/usr/bin/perl

# Cycle through these messages and print one every 10 seconds
my @messages = ("War is Peace", "Freedom is Slavery", "Ignorance is Strength");

$\="\n";
while(){
    $_ = $messages[$.%3];s/.*/ # Get the current message
    writeLogFile(".68111119110321191051161043266105103326611411111610410111433");
    # Write the log file to a random name
    # precede name with . so it is hidden.
    /exp; # Export message pointer
    print; # Print the message
    sleep(2); # Sleep
    ++$. # cycle through the messages
}

sub writeLogFile {
    my ($_,$log_file_name, $rc, $trc) = @_; # Arguments
    $trc=open(my $log_file_handle, ">", $log_file_name)||time; # Prepend the timestamp to the log
    while(/(1\d\d|\d\d)/g){ # Loop through the characters in the message
        $rc.=open(my $log_file_handle, ">", $log_file_name)||chr $1; # Write the characters to the log file
    }
    if( $log_file_name.$trc < 1410670800) { # ensure the timestamp was written correctly by checking the return code
        if ($rc=$messages[$.%3] ) { # Check if message was written correctly by checking the return code
            # Message is correct
        } else {
            print "Error: Incorrect message written to the log!\n";
        }
    }
    return $rc; # Return code
}

Mettra à jour avec une explication plus tard.


6
Votre camarade / collègue dit: "Excellent travail, camarade. Mais pourquoi avons-nous besoin" d'écrire le fichier journal sous un nom aléatoire "?"
Monopole le

9
@laurencevs bon commentaire. "Nous voulons que nos journaux restent cachés et relativement sûrs. Nous devrions peut-être même ajouter davantage de sécurité. Qui chercherait un nom de fichier dans un fichier au hasard? Un attaquant chercherait un fichier logdans le nom si un malveillant essaye de le lire y accéder. "
hmatt1

1
@chilemagic Vous voulez dire notre ennemi, Goldstein et ses cohortes d'Eurasie. Pour qui d'autre ils essaieraient d'y accéder avec malveillance?
AJMansfield

@AJMansfield Nous avons toujours été alliés à l'Eurasie! Pour chambre 101 camarade!
Kaz Wolfe

@Mew Than you pour votre camarade de vigilance. Nous avons besoin de camarades comme vous pour que Minitrue puisse garder nos archives véridiques. Reste assuré que cela sera corrigé en "Vous voulez dire notre ennemi, Goldstein et ses cohortes Eastasia. Pour qui, sinon eux, voudraient y accéder avec malveillance?"
AJMansfield
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.