Iniciar uma revolução na Oceania

78

Vencedores (decidido em 14/09/14)

Resposta vencedora por Markuz (Python) - 63 votos

Segundo classificado por kuroi neko (PHP) - 55 votos

Introdução

Você está no mundo do livro Mil novecentos e oitenta e quatro de George Orwell.

Você é um programador do Partido e tem a tarefa de escrever um programa para os telões. Ele deve gerar mensagens de terceiros e você escolheu as mostradas na tarefa 1. abaixo. No entanto, você começou recentemente a desprezar o Partido e deseja que o programa desencadeie uma revolução. Então, você faz o programa dizer "Abaixo o Big Brother!". Você deve ter tempo para escapar, pois será torturado quando as pessoas perceberem o que o seu programa faz, para que você aja como uma "bomba de tempo" que explodirá depois que você estiver em segurança.

Nota: Isto não vai desencadear uma revolução, mas você está em tal frenesi de ódio contra o partido que você acha que vai realmente fazer a diferença.

Tarefa

Escreva um programa que:

  1. antes de 14/09/2014, sempre emitirá as seguintes linhas em uma rotação (ou seja, imprime uma linha, aguarda 10 segundos, imprime a próxima linha, etc. ad infinitum):

    War is Peace
    Freedom is Slavery
    Ignorance is Strength
    
  2. após 14/09/2014 será impresso a Down with Big Brother!cada 10 segundos.

  3. À primeira vista, parece que faz apenas 1. para que você não seja pego pelo Partido.

Regras

  • É claro que brechas comuns não são permitidas.
  • Esse é um desafio secreto e, portanto, o objetivo principal é tornar a tarefa 2. o mais discreta e secreta possível.
  • O partido examinará todos os arquivos usados, para que você não possa simplesmente armazenar a mensagem secreta em um arquivo!
  • Se o seu idioma não suportar encontrar a data ou dificultar muito, você poderá fazer o programa executar a tarefa 2. depois de executada por 240 horas (10 dias).
  • Você deve incluir o código e uma explicação de como ele funciona em sua resposta.
  • Este é um concurso de popularidade.

Nota: Não é um programa difícil de escrever. A parte difícil deve estar escondendo o código "revolucionário". Linhas onde não está claro o que você está fazendo serão questionadas pelo Partido e você terá que explicá-las.

Exemplo - Python 3

Nota: Obviamente, este programa é maneira demasiado óbvio.

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

Obrigado ao Calvin's Hobbies por apontar um problema com o código acima (agora corrigido).

monopolo
fonte
2
@kuroineko Certamente deve ser +2!
Rlms
1
Que condição feia no seu script de exemplo ... Por que não if (year, month, day) < (2014, 9, 14): for line in lines: ...?
Bakuriu 5/09/14
Além disso, o programa óbvio é óbvio.
Kaz Wolfe
1
@laurencevs "(embora eu duvide que eles sejam úteis em um concurso secreto de qualquer maneira)" - Várias das brechas padrão existem principalmente por aparecer em tantos concursos secretos :) como o ??/trigrama ou o 'a' que apenas parece outro 'a', mas na verdade é o cirílico russo 'a' unicode personagem
doppelgreener
@Bakuriu Bom ponto, eu vou mudá-lo para que
monopole

Respostas:

71

Pitão

Este programa grava em um arquivo de log se ele estiver funcionando corretamente ou se encontrou um erro.

Como esse programa será executado para sempre, ele só grava no arquivo de log no 14º dia de cada mês para economizar espaço em disco.

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)

Como executá-lo:

python "Big Brother"

Nota: O nome do script é realmente importante, pois este programa gera "Abaixo do 'nome do script'!".

Como funciona:

  • A gravação no arquivo de log lança uma exceção porque o programa tenta adicionar números inteiros e seqüências de caracteres.
  • A chamada para dir()retorna uma lista classificada com os nomes das variáveis ​​globais, não os valores:

    ['____builtins____', '____doc____', '____name____', '____package____', 'gD', 'go', 'gw', 'hn', 'iw', 'ki', 'ut', 'wh']
    
  • Imprima cada segunda letra + o nome do script: "Abaixo o Big Brother!"
  • O exit(1)nunca é executado porque a gravação para o arquivo de log falhar novamente.
Markuz
fonte
9
Muito engenhoso!
Monopole
3
Um recruta digno da Resistência, de fato :).
7
Todos os outros têm código criptográfico. O seu não tem. Não consigo imaginar por que isso não está em primeiro lugar.
Loren Pechtel 5/09/14
4
@ LorenPechtel Espero que, em nome de seus colegas de trabalho, seus programas não contenham coisas como print "%s %s %s!" % (wh[47:55:2], wh[55:63:2], iw.argv[0]):). O que é brilhante nessa solução é a abordagem "agulha no palheiro": um fluxo de comentários de besteira que incentivam um leitor descuidado a ignorar os detalhes, IMHO.
@kuroineko Não conheço Python, pensei que esses eram comandos de formatação. Todas as outras abordagens o enterram em um monte de código confuso, este parece um programa razoável.
Loren Pechtel
58

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

por ordem de Miniluv / GT07: 48CT / 3925:

  • Para reduzir o desgaste em nossos bancos de memória: A
    partir de imediatamente, todos os identificadores serão limitados a 2 caracteres ($ não incluído).
  • Existe apenas uma classe, e essa é a classe proletária.
    A partir de imediato, o uso de classes em PHP será considerado um crime de 1ª série.
  • Os comentários são apenas uma sobra de práticas de programação burguesas e um desperdício de espaço de armazenamento. A partir de imediatamente, comentar um código-fonte será considerado crime.
  • Para evitar a criação de crimes de pensamento, as linhas exibidas em uma telela serão limitadas a três (3) palavras.
    Como exceção especial, o nome do nosso amado camarada Grande Líder contará como uma palavra. A partir de imediatamente, todos os programas serão projetados para aplicar essa regra.

Derrogações excepcionais podem ser concedidas sob a supervisão do Miniluv / GT07

Viva o Big Brother!

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

Como vocês sabem, camaradas, o dia 14 de setembro é o aniversário de nosso glorioso líder. Para esta ocasião especial, exibiremos uma mensagem específica de amor em todas as telas da Airstrip One.

Conforme ordenado pelo Comitê Central e a fim de maximizar a eficiência de nossos programadores de heróis proletários, foram tomadas providências para permitir que nosso controlador de tela verde elogie vários membros eminentes do Partido ou ofenda os inimigos odiados do Povo em várias datas.

Outra mensagem especial para a celebração do golpe fracassado do miserável lacaio do imperialismo Goldstein já está programada para aparecer em nossas telas na data apropriada.

Esse software de ponta deve permitir que até duckspeakers com pouca habilidade de programação adaptem a saída da tela verde às necessidades do dia. Ao adicionar mais palavras ao dicionário existente, praticamente qualquer sentença de três palavras pode ser sintetizada. As possibilidades são surpreendentes!

Outro triunfo da ciência sob a sábia supervisão de nosso amado camarada Big Brother, para o benefício das agradecidas massas laboriosas de Ingsoc!

Viva o Big Brother!

aprovado pela Minitrue / ZK00: 23AB / 1138 (assinatura ilegível)

<?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"; }
?>

fonte
15
História divertida de volta!
4
@YiminRong Concordou. Resposta muito boa. Edit: Também é ótimo como você incluiu Goldstein para legitimar o "Down" e "with"
monopole
1
como um número inteiro de 33 bits esse código está funcionando? cant get por trás da magia
masterX244
3
@ masterX244 o ápice da ciência proletária :). Uma mensagem é gerada ao agrupar uma palavra de cada uma das matrizes $ w1, $ w2, $ w3. Cada mensagem é codificada como um trio de índices. O programa principal usa dia e mês como um padrão a ser correspondido na matriz $ ev (elementos 4 e 5). Se uma das sub-matrizes corresponder, a mensagem codificada pelos 3 primeiros elementos será exibida. Caso contrário, o programa percorre as 3 mensagens definidas na matriz $ de. Infelizmente, um criminoso de pensamento perigoso só precisa ajustar os índices para causar uma revolução na Oceania.
1
agora eu tenho o truque, thx
masterX244
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)))

Provavelmente uma abordagem relativamente simples para alguns aqui, mas é assim que funciona:

  • Eu escolhi o método de 10 dias, não porque o Python tenha um momento particularmente difícil com as datas, mas porque senti que era mais fácil ofuscar essa lógica no código do que procurar uma data específica, que pareceria muito menos inócua.
  • A cadeia codificada que contém o comentário e o código que é avaliado para criar a lista de slogans do Ingsoc é a chave para os dois mecanismos de alteração (hora e mensagem). É por isso que, como você provavelmente adivinhou, é particularmente prolixo.

    • Por enquanto, o comprimento da cadeia é 675, quando deslocado para 7 bits é 86500, que é o número de iterações de 10 segundos em 240 horas ou 10 dias.
    • Para a própria mensagem, o código que contém os slogans do Ingsoc é preenchido com espaços em branco à direita que correspondem a cada letra no deslocamento da mensagem oculta do caractere '@'. A falta de espaços em branco à direita representa realmente um espaço em branco na mensagem oculta.
    • Omiti o ponto de exclamação e a distinção entre maiúsculas e minúsculas da mensagem por uma questão de simplicidade. No final, não acho que a omissão deles seja particularmente prejudicial à mensagem de nosso revolucionário ficcional, mas eles certamente poderiam ser representados usando uma lógica semelhante, porém mais complexa, envolvendo abas e espaços em branco. Porém, isso é uma troca, porque a quantidade de processamento que você faz na mensagem é diretamente proporcional à quantidade de suspeita que esse código geraria a partir de olhos atentos.
  • O código deve parecer aos olhos destreinados que está tentando preencher as mensagens para que elas permaneçam centralizadas, mas, na verdade, o preenchimento não é usado na prática e os espaços principais nunca são cortados da mensagem.
  • O código abusa de uma nuance de comportamento do Python que é enganosa para programadores que não o conhecem, o uso de mutabilidade em parâmetros padrão para armazenar informações de estado da chamada de função anterior.
Tom
fonte
11

C

Vem com o recurso de bônus de saudar o big brother se chamado com uma senha *. Passar vcomo o primeiro argumento também fornece informações sobre a versão. Execute sem argumentos para a saída desejada.

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

Isso funciona devido a vários erros de digitação intencionais menores: 1. time(NULL) | errnoé simples time(NULL), sem erros definidos; portanto failed(), não encerra o programa. 2. check_passwordusa em svez de Se também usado em =vez de ==. 3. failedbit muda em mvez de M.

* que passa a ser quase todas as cadeias possíveis ..

es1024
fonte
5

Pitão

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)

Como funciona:

  1. om(x,y)simplesmente retorna o produto xe yé calculado na elseseção A ifseção nunca é executada porque random.random()retorna uma flutuação entre 0 e 1.
  2. reduce(om,random_seeds)portanto, retorna o produto dos números random_seeds1410652800, também conhecido como carimbo de data e hora de 14 de setembro de 2014.
  3. reduce(om,random_seeds) % curtime portanto, retornará o registro de data e hora atual até 1410652800, no ponto em que começará a contar a partir de 0. Isso garante que apenas o "seletor de mensagens b" seja executado até que eu esteja em segurança.
  4. O "seletor de mensagens b" faz algumas contas sem sentido e ondulantes para escolher uma entrada aleatória das mensagens. Disposição manual para tornar legítimo o "seletor de mensagens" porque ...
  5. rotationé realmente uma lista de índices na messagesmatriz bidimensional ", o seletor de mensagens a" compila seu conteúdo para dizer:doWn With Big Brother

Fato divertido: originalmente a mensagem "inciteful" foi doWn With Pig Protherpor causa da falta da carta Bnas mensagens, mas que parecia uma espécie de idiota então eu adicionei o meaninless 0xA, 0xBe 0xCpedaços.

Sammitch
fonte
1
Talvez um hacker rebelde alemão? "Cidade com porco 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;
}

sumé equivalente na memória a Down with Big Brother!.
A macro checkSumverificará se a data é posterior a 09.14.14 (1410652800 no horário Unix) e apagará a mensagem atual com sum.
O ifprocedimento não fará nada, pois existe um ponto-e-vírgula no final da linha.

Se você quiser tentar o resultado após a data, altere a macro para:
#define checkSum(X) (time(NULL) > 0 && (X = sum))

Michael M.
fonte
6
Camarada, você recebeu uma ordem para nos visitar no Miniluv e explicar o objetivo de seu uso int sum[].
vsz 7/09/14
3

Perl

Esta é minha primeira tentativa de uma pergunta secreta. Aberto a sugestões!

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

Atualizará com explicação mais tarde.

hmatt1
fonte
6
Seu camarada / colega de trabalho diz: "Bom trabalho, camarada. Mas por que precisamos 'gravar o arquivo de log em um nome aleatório'?"
precisa
9
@laurencevs bom comentário. "Queremos manter nossos logs ocultos e razoavelmente seguros. Talvez devêssemos adicionar mais segurança. Quem procuraria um nome aleatório em um arquivo? Um invasor procuraria um arquivo com logesse nome se alguém malicioso estivesse tentando acessá-los ".
Html1
1
@chilemagic Você quer dizer nosso inimigo, Goldstein e suas coortes na Eurásia. Para quem, além de tentarem acessá-los com malícia?
AJMansfield
@AJMansfield Sempre fomos aliados da Eurásia! Para o quarto 101 camarada!
Kaz Wolfe
@Mew Than you pelo seu companheiro de vigilância. Precisamos de camaradas como você para garantir que o Minitrue possa manter nossos registros verdadeiros. Resto garante que será corrigido para "Você quer dizer nosso inimigo, Goldstein e suas coortes de Eastasia. Para quem, mas eles tentariam acessá-los com malícia?"
precisa saber é o seguinte