Latar Belakang
Sebuah satu kali pad adalah bentuk enkripsi yang telah terbukti tidak mungkin untuk memecahkan jika digunakan dengan benar.
Enkripsi dilakukan dengan mengambil plaintext (hanya terdiri dari huruf AZ) dan menghasilkan string acak dengan panjang yang sama (juga hanya huruf). String ini bertindak sebagai kunci. Setiap karakter dalam teks plaint kemudian dipasangkan dengan karakter yang sesuai di kunci. Ciphertext dihitung sebagai berikut: Untuk setiap pasangan, kedua karakter dikonversi menjadi angka (A = 0, B = 1, ... Z = 25). Dua angka ditambahkan modulo 26. Angka ini dikonversi kembali menjadi karakter.
Dekripsi justru sebaliknya. Karakter dalam ciphertext dan kunci dipasangkan dan dikonversi menjadi angka. Kuncinya kemudian dikurangi dari modulo 26 ciphertext, dan hasilnya diubah kembali menjadi karakter AZ.
Tantangan
Tantangan Anda adalah menulis program sesingkat mungkin yang bisa mengenkripsi dan mendekripsi pad sekali pakai.
Pada baris input pertama (ke STDIN), akan ada kata "ENCRYPT" atau kata "DECRYPT".
Jika kata itu dienkripsi, maka baris berikutnya akan menjadi teks biasa. Program Anda harus menampilkan dua baris (ke STDOUT), yang pertama adalah kunci, dan yang kedua adalah ciphertext.
Jika kata tersebut didekripsi, program Anda akan mendapatkan dua baris input lagi. Baris pertama akan menjadi kunci, dan baris kedua akan menjadi ciphertext. Program Anda harus menampilkan satu baris, yang akan menjadi teks biasa yang telah didekripsi.
Plaintext, ciphertext, dan key harus selalu terdiri dari huruf besar AZ. Mereka akan selalu menjadi satu baris dan tidak mengandung spasi.
Kuncinya harus selalu acak. Tidak ada bagian besar yang harus diulang di antara run, dan seharusnya tidak ada pola yang dapat ditemukan dalam teks.
Dua contoh sederhana:
ENCRYPT
HAPPYBIRTHDAY
>ABKJAQLRJESMG
>HBZYYRTICLVME
DECRYPT
ABKJAQLRJESMG
HBZYYRTICLVME
>HAPPYBIRTHDAY
The >
mewakili yang garis adalah output, sehingga Anda tidak harus mencetak simbol sebagai output.
sumber
/dev/random
,haveged
), mengenkripsi dengan xoring ords dengan byte dan mendekripsi dengan xoring mereka dengan kunci. gist.github.com/5078264 kunci atau keacakan dapat dibaca dari stdin, pesan atau cyphertext dapat menjadi argumen nama file./dev/hwrng
, alih-alih menggunakan pseudo acak (yang secara teknis membuatnya rusak.)Jawaban:
GolfScript, 53 karakter
Ini adalah tugas yang sepertinya cocok dengan GolfScript.
Untuk menjaga agar kode tetap pendek, saya menggunakan kode yang sama untuk enkripsi dan dekripsi: untuk mendekripsi, saya kurangi kunci dari ciphertext, sedangkan untuk enkripsi, saya pertama-tama membuat ciphertext acak dan kemudian mengurangi plaintext darinya. Meski begitu, kode tambahan untuk menerapkan mode enkripsi hanya membutuhkan sedikit lebih dari setengah panjang program.
Versi de-golf dengan komentar:
sumber
Ruby (
200185)sampel berjalan + wc:
sumber
s[k=(p=f).map{rand 26}],r[k,p,:-]
harus dituliss[k=f.map{rand 26}],r[k,$_,:-]
$_
yang baru saja dibaca oleh baris terakhirgets
.f
juga tidak.scan(/./).map{|b|b.ord-65}
setelah membaca satu baris.Haskell, 203 karakter
Contoh:
sumber
Perl,
220171 karakterContoh Run:
Catatan: setidaknya ketika saya menjalankannya, "Tekan sembarang tombol untuk melanjutkan ..." ditambahkan ke akhir output terakhir. Saya harap ini baik-baik saja, karena ini bukan bagian dari program. Jika tidak, saya bisa membuatnya sehingga muncul di baris berikutnya.
Ini adalah program nyata pertama saya di Perl, dan golf pertama saya, jadi saya akan sangat menghargai tips. Saya juga menemukan
/(.)/g
di internet, tetapi saya tidak tahu cara kerjanya (apakah ini ungkapan reguler? Saya belum mempelajarinya). Adakah yang bisa menjelaskannya kepada saya?EDIT: Terima kasih kepada Ilmari Karonen karena membantu saya dengan regexps, saya menggunakan pengetahuan baru saya untuk menghemat 7 karakter!
Versi yang diperluas dan sedikit terbaca:
sumber
/(.)/g
adalah regexp. Anda pasti ingin belajar itu jika Anda akan bermain golf Perl. perldoc.perl.org/perlre.html bukan tempat awal yang buruk.Python -
304295Saya percaya bahwa ini memenuhi spesifikasi persis
(TermasukIni tidak memvalidasi input, jadi saya pikir itu hanya akan menghasilkan output sampah jika Anda memberikan karakter di luar'>'
di awal input prompt.)[A-Z]
. Itu juga hanya memeriksa huruf pertama dari perintah input. Apa pun yang dimulai denganD
akan menghasilkan dekripsi dan apa pun juga akan menghasilkan enkripsi.sumber
>
, saya hanya menggunakannya untuk menunjukkan jalur mana yang dihasilkan. Anda tidak harus mengimplementasikannya.C ++ -
220241 karakter, 4 barisSunting 1- Perpustakaan standar MSVS tampaknya menyertakan banyak file yang tidak perlu yang berarti bahwa ios memiliki semua yang saya butuhkan tetapi ini tidak bekerja dengan kompiler lain. Mengubah ios untuk file aktual yang dibutuhkan fungsi muncul di cstdlib dan cstdio. Terima kasih kepada Ilmari Karonen karena menunjukkan ini.
sumber
g++ otp.cpp
kataotp.cpp: In function ‘int main()’: otp.cpp:3: error: ‘scanf’ was not declared in this scope otp.cpp:3: error: ‘rand’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope
Python - 270
Output sampel:
Jumlah karakter:
sumber
J: 94 byte
Semua ruang putih yang diperlukan dihitung.
Versi yang dikomentari:
sumber
C # (
445416)Lupa tentang Agregat. Potong sedikit.
Sedikit golf:
}
Golf:
sumber
C (159 + 11 untuk flag compiler)
Golf:
Tidak Disatukan:
Kompilasi dengan
-Dg=gets(s)
.Contoh:
sumber
JavaScript 239
Pemakaian:
sumber
Ruby -
184179177 karakterJalankan seperti ini:
$ ruby pad-lock.rb
Ini adalah versi yang ungolfed jika ada yang tertarik (meskipun tidak cukup dengan versi golf)
sumber