Programm, das eine Nachricht in einen eigenen Text kodiert

13

Schreiben Sie ein Programm, das bestimmten Text in einen eigenen Text codiert, der als Eingabe bereitgestellt wird, ohne seine Logik zu stören. Das Programm muss auch als Decoder arbeiten und die ursprüngliche Nachricht aus ihrem Text wiederherstellen. Es muss seine Codierungs- / Decodierungsfunktionen nach der Transformation beibehalten.

Genauer gesagt muss das erforderliche Programm P die folgenden Transformationen mit dem gegebenen Nachrichtentext M durchführen:
P (M, P) -> P *
P * (P *) -> M

Hier ist P * das transformierte Programm, das auch die obigen Regeln erfüllen muss, das heißt:
P * (M2, P *) -> P **
P ** (P **) -> M2
und so weiter ... Jeder Bei der nachfolgenden Codierung wird zuvor codierter Text nicht gelöscht, sodass P ** zwei Nachrichten enthält - M und M2.

Der einfachste Weg für das Programm, zwischen Codierungs- / Decodierungsmodi zu unterscheiden, ist das Vorhandensein des zusätzlichen Arguments M, aber die endgültige Entscheidung liegt bei Ihnen, sofern dies klar angegeben ist. Das Programm liest möglicherweise seinen eigenen Text aus der Datei. Wenn die gewählte Sprache keine Mittel dafür hat, kann der Quelltext auf andere Weise an das Programm übergeben werden.

Natürlich gibt es triviale Lösungen, daher ist dies eher ein Beliebtheitswettbewerb. Trotzdem schränke ich das Verbieten von Kommentaren im Programmtext ein.

Tr00rle
quelle
Wenn ich das transformierte Programm P * mit einem neuen Text aufrufe, enthält P ** beide Texte oder nur den letzten?
Tal
So bekomme ich den Programmcode als Eingabe beim Kodieren und Dekodieren?
Martin Ender
Wie soll das Programm zwischen der Aufforderung zum Entschlüsseln einer verschlüsselten Nachricht und der Aufforderung zum Verschlüsseln einer Nachricht unterscheiden, die zufällig selbst eine verschlüsselte Nachricht ist?
Celtschk
2
@celtschk Gemessen an der OPs-Notation: Wenn Ihr Programm zwei Eingänge hat, codieren Sie den ersten Eingang in den zweiten Eingang. Wenn das Programm nur eine Eingabe erhält, extrahieren Sie die zuletzt in dieser Eingabe codierte Zeichenfolge.
Martin Ender
4
Sollte es eine Möglichkeit geben, P * von P ** wiederherzustellen? Wenn nicht, warum muss " P ** zwei Nachrichten enthalten - M und M2 "? Es tut mir leid, aber obwohl diese Herausforderung interessant erscheint, ist mir die Spezifikation einfach zu verwirrend.
Ilmari Karonen

Antworten:

8

Perl

Dies ist ein Einzeiler in Perl, nur weil es möglich ist.

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

Die Nachrichten werden nach __DATA__der neuesten zuerst geschrieben.

Greg Hewgill
quelle
Wie wäre es mit einem gesunden Wettbewerb und einem einheitlichen Ausdruck?
Siehe auch
Das ist ein ziemlich großer Wert von einem, den Sie dort haben.
Gilles 'SO- hör auf böse zu sein'
4

Python

Weißt du was? Warum nicht einen einzelnen Ausdruck daraus machen?

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)

Alte Nachricht; Die Funktion P nimmt die angegebenen Argumente und gibt den resultierenden Code / dekodierten Text aus.

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
quelle
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") + ")");
    }
}

Ich bin mir nicht sicher, ob ich die Problembeschreibung richtig verstehe: Mein Decoder decodiert alle Programme und gibt die neueste Nachricht zurück, die im angegebenen Programm codiert ist.

Testcode:

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̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
2

Stapel

@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

Beachten Sie, dass nach 'der letzten Zeile' von ein Wagenrücklauf erfolgen muss goto :EOF.

Dies nimmt zwei Eingaben von stdin entgegen. Der erste ist, was Sie tun möchten; e, oder d(codieren und decodieren). Der zweite Eingang hängt vom ersten ab - wenn der erste Eingang ist e, dann ist der zweite Eingang die Nachricht, die Sie codieren möchten - wenn dies der Fall ist d, ist der zweite Eingang die Nummer der Nachricht, die Sie decodieren möchten (das wird bereitgestellt werden, nachdem eine Nachricht verschlüsselt wurde).

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

H:\uprof>ed.bat d 1
Just a message
unclemeat
quelle
0

Kobra

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)

Während die Idee trivial ist, ist die Ausführung der Idee weniger.

Codierung

Das Codieren einer Nachricht im Programm fügt die Zeile .message = .message ? xunmittelbar danach hinzu def main. Diese Zeile prüft, ob .messageNull ist, und wenn ja, setzt sie.message auf ein ganzzahliges Array gesetzt, das die Zeichencodewerte jedes Zeichens in der Nachricht enthält. Durch die Null-Prüfung und -Positionierung wird vermieden, dass die neue Nachricht mit einer älteren überschrieben wird. Das neue Programm wird in gespeichertencode.cobra

Dekodierung

Beim Dekodieren des Programms werden am Ende der Hauptmethode drei Zeilen hinzugefügt, die bewirken, dass das Programm die Zeichencodes in .messageeine Zeichenfolge konvertiert , die dann message.txtbeim Ausführen des neuen Programms gespeichert wird. Das neue Programm wird dann in gespeichert decode.cobraund der Compiler wird darauf aufgerufen.

decode.cobra wird wie eine temporäre Datei verwendet und kann nicht zum Kodieren oder Dekodieren einer anderen Nachricht verwendet werden. Verwenden Sie das Original oder encode.cobra

Οurous
quelle