Program yang menyandikan pesan ke dalam teksnya sendiri

13

Tulis program yang menyandikan teks yang diberikan ke teksnya sendiri, disediakan sebagai input, tanpa mengganggu logikanya. Program juga harus berfungsi sebagai dekoder, memulihkan pesan asli dari teksnya. Itu harus mempertahankan fungsi encoding / decoding setelah transformasi.

Secara lebih formal, program yang diperlukan P harus melakukan transformasi berikut dengan teks pesan yang diberikan M:
P (M, P) -> P *
P * (P *) -> M

Di sini P * adalah program yang diubah, yang juga harus memenuhi aturan di atas, yaitu:
P * (M2, P *) -> P **
P ** (P **) -> M2
dan seterusnya ... Setiap penyandian selanjutnya tidak menghapus teks yang disandikan sebelumnya, jadi P ** membawa dua pesan - M dan M2.

Cara termudah untuk membedakan program antara mode encoding / decoding adalah dengan adanya argumen tambahan M, tetapi keputusan akhir terserah Anda, asalkan dinyatakan dengan jelas. Program dapat membaca teksnya sendiri dari file. Jika bahasa yang dipilih tidak memiliki sarana untuk ini, teks sumber dapat diteruskan ke program dengan cara lain.

Ada solusi sepele, tentu saja, jadi ini bukan kontes popularitas. Meskipun demikian, saya memaksakan pembatasan untuk melarang komentar dalam teks program.

Tr00rle
sumber
Jika saya memanggil program yang ditransformasikan P * dengan teks baru, apakah P ** berisi kedua teks atau hanya yang terakhir?
Tal
Jadi saya diberi kode program sebagai input saat encoding dan decoding?
Martin Ender
Bagaimana program dimaksudkan untuk membedakan antara yang diminta untuk memecahkan kode pesan yang disandikan, dan yang diminta untuk menyandikan pesan yang kebetulan merupakan pesan yang disandikan sendiri?
celtschk
2
@celtschk dinilai oleh notasi OP: jika program Anda diberi dua input, kodekan input pertama pada input kedua. jika program hanya diberi satu input, ekstrak string yang paling baru disandikan dalam input itu.
Martin Ender
4
Apakah seharusnya ada cara untuk memulihkan P * dari P **? Jika tidak, mengapa mengharuskan " P ** membawa dua pesan - M dan M2 "? Maaf, tetapi meskipun tantangan ini tampaknya menarik, speknya terlalu membingungkan bagi saya.
Ilmari Karonen

Jawaban:

8

Perl

Ini adalah one-liner di Perl hanya karena itu mungkin.

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

Pesan-pesan ditulis setelah __DATA__, paling baru terlebih dahulu.

Greg Hewgill
sumber
Bagaimana dengan persaingan sehat dan ekspresi tunggal?
seequ
Itu nilai yang cukup besar dari yang Anda dapatkan di sana.
Gilles 'SANGAT berhenti menjadi jahat'
4

Python

Kamu tahu apa? Mengapa tidak menjadikannya ekspresi tunggal?

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)

Pesan lama; Fungsi P mengambil argumen seperti yang ditentukan dan mengeluarkan kode yang dihasilkan / teks yang diterjemahkan.

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

Tidak yakin apakah saya memahami pernyataan masalah dengan benar: decoder saya akan mendekode program apa pun dan mengembalikan pesan terbaru yang disandikan dalam program yang diberikan.

Kode uji:

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̷̰̀ĥ̷̳
sumber
2

Batch

@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

Perhatikan harus ada carriage return setelah 'baris terakhir' dari goto :EOF.

Ini mengambil dua input dari stdin. Yang pertama adalah apa yang ingin Anda lakukan; e, atau d(encode dan decode). Input kedua tergantung pada yang pertama - jika input pertama adalah e, maka input kedua akan menjadi pesan yang ingin Anda encode - jika ya d, maka input kedua adalah jumlah pesan yang ingin Anda dekode (yang akan disediakan setelah menyandikan pesan).

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

H:\uprof>ed.bat d 1
Just a message
hapus clemeat
sumber
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)

Meskipun idenya sepele, pelaksanaan ide tersebut kurang begitu.

Pengkodean

Pengkodean pesan dalam program akan menambahkan baris .message = .message ? xsegera setelahnya def main. Baris ini memeriksa apakah .messagenil, dan jika demikian, maka ia menetapkan .messageke array integer yang berisi nilai kode karakter dari setiap karakter dalam pesan; pemeriksaan nil dan penentuan posisi menghindari menimpa pesan baru dengan yang lebih lama. Program baru disimpan keencode.cobra

Decoding

Decoding program akan menambahkan tiga baris di akhir metode utama yang menyebabkan program untuk mengubah kode char .messageke string, yang kemudian disimpan message.txtketika program baru dijalankan. Program baru kemudian disimpan ke decode.cobradan kompiler dipanggil di atasnya.

decode.cobra digunakan seperti file sementara dan tidak dapat digunakan untuk menyandikan atau mendekode pesan lain, gunakan aslinya atau encode.cobra

Suram
sumber