Программа, которая кодирует сообщение в свой собственный текст


13

Напишите программу, которая кодирует данный текст в свой собственный текст, предоставленный в качестве ввода, не нарушая его логику. Программа также должна работать как декодер, восстанавливая исходное сообщение из его текста. Он должен сохранять свои функции кодирования / декодирования после преобразования.

Говоря более формально, требуемая программа P должна выполнить следующие преобразования с заданным текстом сообщения M:
P (M, P) -> P *
P * (P *) -> M

Здесь P * - преобразованная программа, которая также должна удовлетворять вышеуказанным правилам, а именно:
P * (M2, P *) -> P **
P ** (P **) -> M2
и так далее ... Каждая последующее кодирование не стирает ранее закодированный текст, поэтому P ** несет два сообщения - M и M2.

Самый простой способ для программы отличить режимы кодирования / декодирования - это наличие дополнительного аргумента M, но окончательное решение остается за вами, если оно четко указано. Программа может прочитать свой собственный текст из файла. Если на выбранном языке нет средств для этого, исходный текст можно передать в программу любым другим способом.

Конечно, есть тривиальные решения, так что это скорее конкурс популярности. Тем не менее, я накладываю ограничение на запрет комментариев в тексте программы.


Если я вызываю преобразованную программу P * с новым текстом, содержит ли P ** оба текста или только последний?
Тал

Таким образом, мне дают код программы в качестве ввода при кодировании и декодировании?
Мартин Эндер

Как программа предназначена для того, чтобы различать запрос на декодирование закодированного сообщения и запрос на кодирование сообщения, которое само по себе является закодированным сообщением?
celtschk

2
@celtschk, судя по записи OP: если вашей программе дано два входа, закодируйте первый вход во втором входе. если программе дается только один вход, извлеките строку, наиболее недавно закодированную в этот вход.
Мартин Эндер

4
Должен ли быть какой-либо способ восстановить P * из P **? Если нет, зачем требовать, чтобы « P ** переносил два сообщения - M и M2 »? Извините, но хотя этот вызов кажется интересным, спецификация слишком запутанная для меня.
Илмари Каронен

Ответы:


8

Perl

Это одна строка в Perl только потому, что это возможно.

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

Сообщения пишутся после __DATA__, самые последние сначала.


Как насчет здоровой конкуренции и единственного выражения?
Seequ

Это довольно большая ценность того, что у вас есть.
Жиль "ТАК - перестать быть злым"

4

питон

Знаешь что? Почему бы не сделать это одним выражением?

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)

Старое сообщение; Функция P принимает указанные аргументы и выводит полученный код / ​​декодированный текст.

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)

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

Не уверен, правильно ли я понимаю формулировку проблемы: мой декодер будет декодировать любую программу и возвращает последнее сообщение, закодированное в данной программе.

Тестовый код:

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

2

партия

@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

Обратите внимание, что после «последней строки» должен быть возврат каретки goto :EOF.

Это берет два ввода от стандартного ввода. Первое, что вы хотите сделать; eили d(кодировать и декодировать). Второй вход зависит от первого - если первый вход есть e, то вторым входом будет сообщение, которое вы хотите закодировать - если это так d, то вторым входом будет номер сообщения, которое вы хотите декодировать (который будет предоставляется после кодирования сообщения).

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

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

0

кобра

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)

Пока идея тривиальна, исполнение указанной идеи менее реальна.

кодирование

Кодирование сообщения в программе добавит строку .message = .message ? xсразу после def main. Эта строка проверяет, имеет ли значение .messagenil, и если да, то устанавливает .messageцелочисленный массив, содержащий значения кодов символов каждого символа в сообщении; нулевая проверка и позиционирование позволяют избежать перезаписи нового сообщения более старым. Новая программа сохранена вencode.cobra

Декодирование

При декодировании программы в конце основного метода добавляются три строки, которые заставляют программу преобразовывать коды символов в .messageстроку, которая затем сохраняется message.txtпри запуске новой программы. Новая программа затем сохраняется decode.cobraи вызывается компилятор.

decode.cobra используется как временный файл и не может использоваться для кодирования или декодирования другого сообщения, использования оригинала или encode.cobra

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.