Programa que codifica un mensaje en su propio texto.

13

Escriba un programa que codifique el texto dado en su propio texto, proporcionado como entrada, sin interrumpir su lógica. El programa también debe funcionar como decodificador, restaurando el mensaje original de su texto. Debe conservar sus funciones de codificación / decodificación después de la transformación.

Hablando más formalmente, el programa requerido P debe realizar las siguientes transformaciones con el mensaje de texto M:
P (M, P) -> P *
P * (P *) -> M

Aquí P * es el programa transformado, que también debe satisfacer las reglas anteriores, es decir:
P * (M2, P *) -> P **
P ** (P **) -> M2
y así sucesivamente ... Cada la codificación posterior no borra el texto codificado previamente, por lo que P ** lleva dos mensajes: M y M2.

La forma más fácil para que el programa distinga entre los modos de codificación / decodificación es mediante la presencia del argumento adicional M, pero la decisión final depende de usted, siempre y cuando se establezca claramente. El programa puede leer su propio texto del archivo. Si el idioma elegido no tiene medios para esto, el texto fuente se puede pasar al programa de cualquier otra manera.

Existen soluciones triviales, por supuesto, por lo que este es un concurso de popularidad. Sin embargo, impongo restricciones que prohíben los comentarios en el texto del programa.

Tr00rle
fuente
Si llamo al programa transformado P * con un nuevo texto, ¿P ** contiene ambos textos o solo el último?
Tal
¿Entonces me dan el código de los programas como entrada cuando codifico y decodifico?
Martin Ender
¿Cómo se pretende que el programa distinga entre que se le pida que decodifique un mensaje codificado y que se le pida que codifique un mensaje que resulta ser un mensaje codificado?
celtschk
2
@celtschk a juzgar por la notación de OP: si su programa recibe dos entradas, codifique la primera entrada en la segunda entrada. si el programa recibe solo una entrada, extraiga la cadena codificada más recientemente en esa entrada.
Martin Ender
44
¿Se supone que hay alguna forma de recuperar P * de P **? Si no es así, ¿por qué exigir que " P ** lleve dos mensajes: M y M2 "? Lo siento, pero aunque este desafío parece interesante, la especificación es demasiado confusa para mí.
Ilmari Karonen

Respuestas:

8

Perl

Esta es una frase en Perl solo porque es posible.

if($ARGV[0]){open(F,__FILE__);while(<F>){print;print"$ARGV[0]\n"if/^_/;}}else{print<DATA>;}
__DATA__

Los mensajes se escriben después __DATA__, el más reciente primero.

Greg Hewgill
fuente
¿Qué tal una sana competencia y una sola expresión?
seequ
Ese es un valor bastante grande de uno que tienes allí.
Gilles 'SO- deja de ser malvado'
4

Pitón

¿Sabes que? ¿Por qué no convertirlo en una sola expresión?

P = (lambda M,P=None:(lambda t:P[:74]+repr(M)[1:-1]+"'))"if P else M[74:-3])(''))
Pc = "(lambda M,P=None:(lambda t:P[:74]+repr(M)[1:-1]+\"'))\"if P else M[74:-3])(''))"
P2c = P('Hi there, mate!', Pc)
print "Encode tests:"
print " P2 = P('Hi there, mate!', Pc) =", P2c
exec 'P2 = ' + P2c
print " P2(\"Test 2's the best.\", P2c) =", P2("Test 2's the best.", P2c)

print "Decode tests:"
print "P2(P2) =", P2(P2c)
print "P(P2)  =", P(P2c)
print "P2(P)  =", P2(Pc)
print "P(P)   =", P(Pc)

Viejo mensaje; La función P toma los argumentos como se especifica y genera el código resultante / texto decodificado.

def P(data,func=None):
    text = ""
    if func:
        return func[:35]+data+'"\n'+'\n'.join(func.split('\n')[2:])
    return data[35:].split('\n')[0][:-1]

# The source code.
Pc = """def P(data,func=None):
    text = ""
    if func:
        return func[:35]+data+'"\\n'+'\\n'.join(func.split('\\n')[2:])
    return data[35:].split('\\n')[0][:-1]"""

P2c = P('Hi there, mate!', Pc)
print "Encode test:"
print "P('Hi there, mate!', P) ->"
print P2c

# This is outputted by P('Hi there, mate!', code-of-P)
def P2(data,func=None):
    text = "Hi there, mate!"
    if func:
        return func[:35]+data+'"\n'+'\n'.join(func.split('\n')[2:])
    return data[35:].split('\n')[0][:-1]

print "P2('Text 2', P2) -<"
print P2('Text 2', P2c)

print "Decode test:"
print "P2(P2) =", P2(P2c)
print "P(P2)  =", P(P2c)
print "P2(P)  =", P2(Pc)
print "P(P)   =", P(Pc)
seequ
fuente
2

JavaScript

var transform = function (p, m) {
    var _M_ = '';
    var source = arguments.callee.toString();
    var msgre = /(_M_ = ').*(';)/;
    var regex = new RegExp(source.replace(/[.*+?^$\[\]{}()\\|]/g, "\\$&").replace(msgre, "$1(.*)$2"));

    var a = p.toString().match(regex);

    if (!a) {
        throw "first argument must be a transform function"
    } else {
        a = a[1];
    }

    if (typeof m == "undefined") {
        return eval("[" + a.split("|")[0] + "]").map(x=>String.fromCharCode(x)).join("");
    } else {
        a = m.toString().split("").map(x => x.charCodeAt(0)) + (a.length ? "|" + a: a);
        return eval("(" + source.replace(msgre, "$1" + a + "$2") + ")");
    }
}

No estoy seguro si entiendo la declaración del problema correctamente: mi decodificador decodificará cualquier programa y devolverá el último mensaje codificado en el programa dado.

Código de prueba:

P1 = transform(transform, "first message");
P2 = P1(P1, "second message");

console.log(P1(P1));
console.log(P2(P2));

console.log(P2(P1));
console.log(P1(P2));

// Unspecified behavior
console.log(transform(transform))
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fuente
2

Lote

@echo off

setLocal enableDelayedExpansion
for /f %%a in (%0) do set a=%%a

if "%~1"=="e" (
    set /a a+=1
    echo !a! %~2 >> %0
    echo message encoded as !a!
) else if "%~1"=="d" for /f "skip=12 tokens=1*" %%a in (%0) do if "%%a"=="%~2" echo %%b

goto :EOF

Tenga en cuenta que debe haber un retorno de carro después de 'la última línea' de goto :EOF.

Esto toma dos entradas de stdin. El primero de los cuales es lo que quieres hacer; e, o d(codificar y decodificar). La segunda entrada depende de la primera; si la primera entrada es e, entonces la segunda entrada será el mensaje que desea codificar; si es así d, la segunda entrada será el número del mensaje que desea decodificar (eso se proporcionará después de codificar un mensaje).

H:\uprof>ed.bat e "Just a message"
message encoded as 1

H:\uprof>ed.bat d 1
Just a message
carne sin carne
fuente
0

Cobra

use System.Diagnostics
class Program
    var message as int[]? = nil
    def decode(program as String)
        temp = List<of String>(program.split('\n'))
        temp.insert(4, '\t\tEnvironment.exit(0)')
        temp.add('\t\tmessage = \'\'')
        temp.add('\t\tfor i in .message, message += Convert.toString(i to char)')
        temp.add('\t\tFile.writeAllText(\'message.txt\', message)')
        program = temp.join('\n')
        File.writeAllText('decode.cobra', program)
        process = Process()
        process.startInfo.fileName = 'cmd.exe'
        process.startInfo.arguments = '/C cobra decode.cobra'
        process.start
    def encode(message as String, program as String)
        temp = List<of String>()
        for i in message.toCharArray, temp.add(Convert.toString(i to int))
        message = '@' + Convert.toString(c'[')
        for n in temp.count-1, message += temp[n] + ','
        message += temp.pop + ']'
        temp = List<of String>(program.split('\n'))
        temp.insert(26,'\t\t.message = .message ? [message]')
        program = temp.join('\n')
        File.writeAllText('encode.cobra', program)
    def main
        #call methods here
        #.encode(message, program)
        #.decode(program)

Si bien la idea es trivial, la ejecución de dicha idea no lo es tanto.

Codificación

Codificar un mensaje en el programa agregará la línea .message = .message ? xinmediatamente después def main. Esta línea verifica si .messagees nula, y si es así, se establece .messageen una matriz entera que contiene los valores del código de caracteres de cada carácter en el mensaje; la comprobación nula y el posicionamiento evitan sobrescribir el nuevo mensaje con uno anterior. El nuevo programa se guarda enencode.cobra

Descodificación

La decodificación del programa agregará tres líneas al final del método principal, lo que hará que el programa convierta los códigos de caracteres en .messageuna cadena, que luego se guardará message.txtcuando se ejecute el nuevo programa. El nuevo programa se guarda decode.cobray se invoca el compilador.

decode.cobra se usa como un archivo temporal y no se puede usar para codificar o decodificar otro mensaje, use el original o encode.cobra

Οurous
fuente