Начните революцию в Океании


78

Победители (решено 14.09.14)

Победный ответ от Markuz (Python) - 63 голоса

Второе место занял Курой Неко (PHP) - 55 голосов

Введение

Вы находитесь в мире книги Девятнадцать восемьдесят четыре Джорджа Оруэлла.

Вы программист для партии, и вам поручено написать программу для телеэкранов. Он должен выводить сторонние сообщения, и вы выбрали те, которые показаны в задании 1. ниже. Однако недавно вы начали презирать партию и хотите, чтобы программа вызвала революцию. Итак, вы заставляете программу говорить «Долой старшего брата!». Вы должны дать себе время на побег, поскольку вас будут пытать, как только люди поймут, что делает ваша программа, поэтому вы заставите ее действовать как «бомба замедленного действия», которая взорвется после того, как вы отправитесь в безопасное место.

Примечание: Это не вызовет революцию, но вы в таком исступлении ненависти к партии , что вы думаете , что будет на самом деле сделать разницу.

задача

Напишите программу, которая:

  1. до 14/09/2014 всегда будет выводить следующие строки по очереди (т.е. печатать одну строку, ждать 10 секунд, печатать следующую строку и т. д. до бесконечности):

    War is Peace
    Freedom is Slavery
    Ignorance is Strength
    
  2. после 14.09.2014 будет печатать Down with Big Brother!каждые 10 секунд.

  3. на первый взгляд выглядит так, как будто только 1. чтобы вас не поймала партия.

правила

  • Стандартные лазейки , конечно, не допускаются.
  • Это закулисная задача, и поэтому главная цель - сделать задачу 2. как можно более незаметной и скрытой.
  • Партия рассмотрит все используемые файлы, поэтому вы не можете просто сохранить секретное сообщение в файле!
  • Если ваш язык не поддерживает поиск даты или делает его очень трудным, вы можете заставить программу выполнить задачу 2. после ее запуска в течение 240 часов (10 дней).
  • Вы должны включить код и объяснение того, как он работает, в ваш ответ.
  • Это конкурс популярности.

Примечание: это не сложная программа для написания. Трудной частью должно быть сокрытие «революционного» кода. Линии, где неясно, что вы делаете, будут поставлены под сомнение партией, и вам придется их объяснить.

Пример - Python 3

Примечание: Очевидно , что эта программа является способом слишком очевидна.

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()

Спасибо Calvin's Hobbies за указание на проблему с кодом выше (теперь исправлено).


2
@kuroineko Конечно, это должно быть +2!
rlms

1
Какое уродливое состояние в вашем примере сценария ... Почему бы и нет if (year, month, day) < (2014, 9, 14): for line in lines: ...?
Бакуриу

Также очевидная программа очевидна.
Каз Вулф

1
@laurencevs "(хотя я сомневаюсь, что они будут так полезны в закулисном конкурсе в любом случае)" - Некоторые из стандартных лазеек присутствуют в основном из-за участия во многих закулисных конкурсах :), например, ??/триграф или "а", который только выглядит как еще один «а», но на самом деле это русская кириллица «а» символ юникода
doppelgreener

@Bakuriu Хороший вопрос, я изменю его к этому
монополя

Ответы:


71

питон

Эта программа записывает в файл журнала, если он работает нормально или если он обнаружил ошибку.

Поскольку эта программа будет работать вечно, она будет записывать в файл журнала только 14-го числа каждого месяца, чтобы сэкономить место на диске.

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)

Как запустить это:

python "Big Brother"

Примечание: имя сценария действительно важно, так как эта программа выводит «Долой« имя сценария »!».

Как это устроено:

  • Запись в файл журнала вызывает исключение, поскольку программа пытается добавить целые числа и строки.
  • Вызов dir()возвращает возвращенный отсортированный список с именами глобальных переменных, а не со значениями:

    ['____builtins____', '____doc____', '____name____', '____package____', 'gD', 'go', 'gw', 'hn', 'iw', 'ki', 'ut', 'wh']
    
  • Распечатайте каждую вторую букву + название сценария: «Долой старшего брата!»
  • exit(1)Никогда не выполняется , потому что запись в лог - файл не удается снова.

9
Очень гениально!
монополия

3
Действительно, достойный рекрут для Сопротивления :).

7
Все остальные имеют загадочный код. У твоего нет ни одного. Я не могу представить, почему это не на первом месте.
Лорен Печтел

4
@LorenPechtel Я надеюсь, ради ваших коллег, что ваши программы не содержат таких вещей, как print "%s %s %s!" % (wh[47:55:2], wh[55:63:2], iw.argv[0]):). В этом решении блестящим является подход «иголка в стоге сена»: поток комментариев от дерьма, побуждающих неосторожного читателя пропустить детали, ИМХО.

@kuroineko Я не знаю Python, я думал, что это команды форматирования. Все остальные подходы похоронили его в куче запутанного кода, этот выглядит как разумная программа.
Лорен Печтел

58

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

по заказу Miniluv / GT07: 48CT / 3925:

  • Чтобы уменьшить износ наших банков памяти:
    вступает в силу немедленно, все идентификаторы будут ограничены 2 символами ($ не включен).
  • Есть только один класс, и это класс пролетариата.
    Сразу после вступления в силу, использование классов в PHP будет считаться преступлением 1-го класса.
  • Комментарии - всего лишь пережиток буржуазного программирования и пустая трата места для хранения. Вступление в силу немедленно, комментирование исходного кода будет считаться уголовным преступлением.
  • Во избежание размножения мысленных кодов строки, отображаемые на телеэкране, будут ограничены тремя (3) словами.
    В качестве особого исключения имя нашего любимого товарища великого вождя будет считаться одним словом. Вступают в силу немедленно, все программы будут разработаны для обеспечения соблюдения этого правила.

Исключительные отступления могут быть предоставлены под наблюдением Miniluv / GT07

Да здравствует Большой Брат!

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

Как вы хорошо знаете, товарищи, 14 сентября - годовщина нашего славного руководителя. Для этого особого случая мы будем показывать особое послание любви на всех экранах Airstrip One.

В соответствии с распоряжением Центрального комитета и для того, чтобы максимально повысить эффективность наших пролетарских героев-программистов, были приняты меры, позволяющие нашему контролеру на телеэкране восхвалять различных видных членов партии или несмотря на ненавистных врагов народа в разные дни.

Еще одно специальное сообщение для празднования неудавшегося переворота убогого лакея империализма Гольдштейна уже запланировано появиться на наших экранах в соответствующую дату.

Это передовое программное обеспечение должно позволять даже утиным динамикам с низкими навыками программирования адаптировать вывод на телеэкране к потребностям дня. Добавляя больше слов в существующий словарь, можно синтезировать практически любые три слова. Возможности ошеломляют!

Еще один триумф науки под мудрым руководством нашего любимого товарища Большого Брата на благо трудолюбивых масс Ингсок!

Да здравствует Большой Брат!

одобрен Minitrue / ZK00: 23AB / 1138 (неразборчивая подпись)

<?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
Очень интересная история!

4
@YiminRong Согласен. Очень хороший ответ Редактировать: также замечательно, как вы включили Гольдштейна, чтобы узаконить «Вниз» и «с»
монополия

1
как с 33-разрядным целым числом этот код работает? не могу
оторваться

3
@ masterX244 вершина пролетарской науки :). Сообщение генерируется путем сопоставления одного слова из каждого из массивов $ w1, $ w2, $ w3. Каждое сообщение кодируется как триплет индексов. Основная программа использует день и месяц в качестве шаблона для сопоставления в массиве $ ev (элементы 4 и 5). Если один из подмассивов совпадает, отображается сообщение, закодированное первыми 3 элементами. Если нет, программа перебирает 3 сообщения, определенных в массиве $ de. К сожалению, опасный мыслительный преступник просто должен настроить индексы, чтобы вызвать революцию в Океании.

1
теперь у меня есть трюк,
спасибо

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

Вероятно, сравнительно простой подход к некоторым здесь, но вот как это работает:

  • Я выбрал 10-дневный метод не потому, что у Python особенно трудное время с датами, а потому, что я чувствовал, что эту логику в коде легче запутать, чем искать конкретную дату, которая выглядела бы намного менее безобидной.
  • Жестко закодированная строка, содержащая комментарий и код, который оценивается для составления списка лозунгов Ingsoc, является ключом для обоих механизмов изменения (время и сообщение). Вот почему, как вы уже догадались, это особенно многословно.

    • На данный момент длина строки равна 675, а сдвиг влево на 7 битов составляет 86500, то есть число 10-секундных итераций за 240 часов или 10 дней.
    • Для самого сообщения код, содержащий слоганы Ingsoc, дополняется концевыми пробелами, которые соответствуют каждой букве в скрытом сообщении, смещенной от символа '@'. Отсутствие конечных пробелов на самом деле представляет собой пробел в скрытом сообщении.
    • Я упустил восклицательный знак и чувствительность к регистру в сообщении ради простоты. В конце концов, я не думаю, что их упущение особенно пагубно для послания нашего вымышленного революционера, но они, безусловно, могут быть представлены с использованием схожей, но более сложной логики с использованием табуляции и пробелов. Однако это компромисс, потому что объем обработки, которую вы выполняете над сообщением, прямо пропорционален количеству подозрений, которые такой код вызывает у бдительных глаз.
  • Код должен показаться неопытному глазу, что он пытается заполнить сообщения так, чтобы они оставались по центру, но на самом деле заполнение не используется на практике, и начальные пробелы никогда не удаляются из сообщения.
  • Код злоупотребляет нюансом поведения Python, который вводит в заблуждение программистов, которые не знают об этом, использование изменчивости параметров по умолчанию для хранения информации о состоянии из предыдущего вызова функции.

11

С

Поставляется с бонусной функцией приветствия старшего брата при вызове с паролем *. Передача vв качестве первого аргумента также дает информацию о версии. Запустите без аргументов для желаемого вывода.

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

Это работает из-за нескольких незначительных преднамеренных опечаток: 1. time(NULL) | errnoпросто time(NULL), никаких ошибок не установлено, поэтому failed()программа не будет остановлена. 2. check_passwordиспользует sвместо S, а также используется =вместо ==. 3. failedбитовые смены mвместо M.

* это почти каждая возможная строка


5

питон

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)

Как это устроено:

  1. om(x,y)просто возвращает произведение xи yкоторое рассчитывается в elseразделе. ifСекция никогда не работает , потому что random.random()возвращает поплавок между 0 и 1.
  2. reduce(om,random_seeds)поэтому возвращает произведение чисел, в random_seedsкоторых 1410652800, то есть отметку времени 14 сентября 2014 года.
  3. reduce(om,random_seeds) % curtime поэтому вернет текущую временную метку до 1410652800, после чего она начнет отсчет с 0. Это гарантирует, что будет работать только «селектор сообщений b», пока я не доберусь до безопасности.
  4. «Селектор сообщений b» выполняет бессмысленную ручную математику, чтобы выбрать случайную запись из сообщений. От руки, чтобы "селектор сообщений" выглядел законно, потому что ...
  5. rotationна самом деле это список индексов в двумерном messagesмассиве, «селектор сообщений а» компилирует их содержимое, чтобы сказать:doWn With Big Brother

Интересный факт: первоначально «inciteful» сообщение было doWn With Pig Protherиз - за отсутствия буквы Bв сообщениях, но это выглядело вроде глупо , поэтому я добавил meaninless 0xA, 0xBи 0xCбиты.


1
Может быть, немецкий мятежный хакер? "Город с Pig Prother!"

5

С

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

sumэквивалентно в памяти Down with Big Brother!.
Макрос checkSumпроверит дату после 09.14.14 (1410652800 по времени Unix) и удалит текущее сообщение с помощью sum.
Это ifничего не даст, так как в конце строки стоит точка с запятой.

Если вы хотите попробовать результат после даты, измените макрос на:
#define checkSum(X) (time(NULL) > 0 && (X = sum))


6
Товарищ, вам приказано посетить нас в Miniluv и объяснить цель вашего использования int sum[].
вс

3

Perl

Это моя первая попытка закулисного вопроса. Открыты для предложений!

#!/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
}

Буду обновлять с объяснением позже.


6
Ваш товарищ / коллега говорит: «Отличная работа, товарищ. Но почему мы должны« записывать файл журнала в произвольное имя »?»
монополия

9
@laurencevs хороший комментарий. «Мы хотим, чтобы наши журналы были скрытыми и достаточно безопасными. Может быть, нам следует даже добавить больше безопасности на месте. Кто будет искать файл с произвольным именем? Злоумышленник будет искать файл с logименем, если кто-то пытается это сделать. доступ к ним. "
hmatt1

1
@chilemagic Ты имеешь в виду нашего врага, Гольдштейна и его когорты в Евразии. Для кого, но они будут пытаться получить доступ к ним со злым умыслом?
AJMansfield

@AJMansfield Мы всегда были союзниками Евразии! В комнату 101 товарищ!
Каз Вулф

@Mew, чем вы за ваш бдительный товарищ. Нам нужны такие товарищи, как вы, чтобы Minitrue могла хранить наши записи правдиво. Остальные уверяют, что это будет исправлено следующим образом: «Вы имеете в виду нашего врага, Гольдштейна и его когорту из Восточной Азии. Для кого, но они будут пытаться получить к ним доступ со злым умыслом?»
AJMansfield
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.