Enkripsi jendela PI


13

Ini adalah metode enkripsi sederhana yang menggunakan digit PI untuk menyandikan pesan, metode ini sederhana:

Kuncinya hanyalah bilangan bulat positif yang menunjukkan dari mana jendela dimulai kemudian:

Diberikan string untuk mengenkripsi, hanya berisi huruf kecil, tanpa spasi, Anda mengambil panjangnya, kemudian Anda menemukan digit N dari PI dan kemudian mulai menggeser setiap huruf ke kanan untuk jumlah yang ditunjukkan oleh digit.

Misalnya, jika kuncinya adalah 2dan saya ingin menyandikan house, saya mengambil jendela 5 digit dari yang kedua: 14159dan kemudian menjadi:

h -> i
o -> s
u -> v
s -> x
e -> n

a.- Program / fungsi / algoritma Anda akan menerima dua parameter, string yang hanya terdiri dari huruf kecil tanpa spasi dan kunci, yang akan menjadi bilangan bulat positif antara 1 (1 merujuk ke 3) dan 1000, yang bisa lebih atau kurang karena saya tidak yakin berapa lama waktu yang dibutuhkan untuk menghitung PI dengan akurasi yang disebutkan karena:

b.- Anda harus menghitung PI sendiri dalam kode Anda, berikut adalah laman web yang rapi untuk dibandingkan dengan: Pi Day . Input seharusnya tidak membuat Anda menghitung PI melebihi 1000 digit, yang berarti panjang (pesan) + kunci <= 1000.

Dengan menghitung Pi, maksud saya tidak memasukkan kode itu ke dalam kode Anda (konyol untuk golf kode) atau menggunakan konstanta yang disematkan dalam kode Anda atau identitas trigonometrik (2 * acos (0)) atau referensi web apa pun.

c.- Outputnya hanya berupa string terenkripsi.

Ini adalah pertanyaan kode golf, kode pendek menang!

Saya akan menerima jawaban yang menang pada 14 Juli 2014.


1
Apa yang terjadi ketika huruf digeser melewati akhir alfabet? Apakah membungkus ke awal alfabet terjadi atau sesuatu yang lain?
Digital Trauma

1
Ya, Anda baru saja memulai dari awal.
BrunoJ

6
Apa yang dianggap sebagai "hitung dirimu"? ArcCos(-1)?
Martin Ender

1
Saya menjelaskan lebih baik apa yang ingin saya katakan dengan menghitungnya sendiri dan menunjukkan bahwa 3 adalah digit pertama.
BrunoJ

1
Ini sebenarnya tampak seperti algoritma enkripsi yang sangat cerdas, mengapa ini tidak banyak digunakan (kecuali dengan konstanta yang lebih rumit seperti e ^ pi atau sesuatu yang kurang dapat dikenali)?
ASKASK

Jawaban:


3

CJam - 51

l_,li(2e4,-2%{2+_2/@*\/2e2000+}*Ab><]z{~+_'z>26*-}%

Input contoh:

zebra
20

Keluaran:

dkdxe

Ini berfungsi untuk (panjang string) + kunci <= 2000, tetapi cukup lambat untuk juru bahasa online (masih cepat dengan juru bahasa java).

Berikut adalah versi yang berfungsi hingga 200 dan Anda dapat mencoba di http://cjam.aditsu.net/ tanpa menunggu terlalu lama:

l_,li(2e3,-2%{2+_2/@*\/2e200+}*Ab><]z{~+_'z>26*-}%

5

Python - 370

Ok, bagus, akhirnya menyelesaikan hal pi berkat link1 dan link2 .

from decimal import *
def f(s,n): 
 j=len(s)
 getcontext().prec=j+n+5
 d=Decimal
 e=d(0)
 for k in range(0,j+n+5): 
  e+=(d(16)**(-k)*(d(4)/(8*k+1)-d(2)/(8*k+4)-d(1)/(8*k+5)-d(1)/(8*k+6)))
 c=`e`.split("'")[1].replace('.','')
 t=''
 for i,l in enumerate(s):
  o=ord(l)
  for v in[0,32]:
   if 64+v<o<91+v:
    l=chr(((o-65-v)+int(c[i+n-1]))%26+65+v)
  t+=l   
 print t

Contoh output:

>>> f('house',2)
isvxn

dan lainnya:

Wimt fcy d dnyh uhkvkv qhvadil   

>>> f ('Ini adalah pesan yang sangat rahasia', 1)


1

JavaScript - 167 173 176

Terima kasih kepada Michael untuk representasi cerdas dari kekuatan 16.

Ini dapat menghitung PI hingga digit ke-16.

function e(s,o){for(p=i=n=r='',m=1;s[+i];m<<=4,n>o?r+=String.fromCharCode(s.charCodeAt(i)-+-(1e15*p+'')[o+i++]):0)p-=(4/((d=8*n++)+1)-2/(d+=4)-1/++d-1/++d)/m;return r}

Kasus uji:

> e("house",2)
"isvxn"

Bagaimana dengan m=1dan m<<=4bukannya m='0x1'dan m+=0? Menghemat 3 byte
Michael M.

1

Python - 321 304 288 285

from decimal import*
d=Decimal
s,n=raw_input(),input()
l=len(s)
getcontext().prec=n+l
print''.join([chr((v-97)%26+97)for v in map(sum,zip(map(ord,s),map(int,str(sum([(d(4)/(8*k+1)-d(2)/(8*k+4)-d(1)/(8*k+5)-d(1)/(8*k+6))/16**k for k in range(0,l+n)])).replace('.','')[n-1:n+l])))])

Sebagian besar versi golf mudah dibaca dan dipahami. Baris terakhir tidak dipisahkan di bawah ini:

# Calculate PI using the BBP formula.
pi = 0
for k in range(0,l+n):
    pi += (d(1)/(16**k))*((d(4)/(8*k+1))-(d(2)/(8*k+4))-(d(1)/(8*k+5))-(d(1)/(8*k+6)))

# Remove the decimal point in PI.
pi = str(pi).replace('.','')

result = []
# For the ASCII sum of each pair of letters in `s` and its digit in PI 
for v in sum(zip(map(ord, s), map(int, pi))):
    result.append((v-97)%26+97)

# Convert all the ordinal values to characters
print ''.join(map(chr, result))

EDIT # 1: menyederhanakan modul hitung saya.

EDIT # 2: refactored formula BBP.


0

Haskell - 265 267 byte (tidak ada IO)

p=g(1,0,1,1,3,3)where g(q,r,t,k,n,l)=if 4*q+r-t<n*t then n:g(10*q,10*(r-n*t),t,k,div(10*(3*q+r))t-10*n,l) else g(q*k,(2*q+r)*l,t*l,k+1,div(q*(7*k+2)+r*l)(t*l),l+2)
e i s=zipWith(\k c->toEnum$fromIntegral k+fromEnum c::Char)(take(length s)$drop(fromIntegral$i-1)p)s

padalah versi algoritme golf yang dapat ditemukan di http://rosettacode.org/wiki/Pi#Haskell

e adalah fungsi encoding:

λ> e 2 "house"
"isvxn"

Itu tidak berputar jika indeks berada di luar alfabet huruf kecil. Ini berarti bahwa beberapa karakter lain dapat masuk ke string yang disandikan:

"Sfufv#Kork(mq}nns j{i&sv&xitmujtu&vey|h{xljej|35.)(\"%(\"\"&\" %\"\"$()$ ''\"&'!)$'(\"&($(\"& !$'&)]hrs\"ow olih7$Tdkhnsj ns&qpdlw}oplwmxbipn#o{ur!vhbp\"mitj/"

Sayangnya, dibutuhkan beberapa detik dengan offset lebih besar daripada 10 000untuk menghitung output. Untungnya, ketika menggunakan offset yang sama beberapa kali, digit hanya harus dihitung pertama kali.

Bonus - Decoding

d i s=zipWith(\k c->toEnum$fromEnum c-fromIntegral k::Char)(take(length s)$drop(i-1)p)s

Sekali lagi jika kami uji dengan isvxn:

λ> d 2 "isvxn"
"house"

Buat salah ketik di bagian bonus Anda. d 2 "isvsn"seharusnyad 2 "isvxn"
Spedwards

Tetap. Terima kasih telah memperhatikan.
gxtaillon

0

CoffeeScript - 148 Chars / Bytes

Golf Code pertama saya

Sayangnya Ini tidak mendukung pembungkus (Jadi az akan berakhir dengan tanda baca)

e = (m, k) -> (m.split (''). map (v, i) -> String.fromCharCode v.charCodeAt () + parseInt Math.PI.toString (). ganti ('.', '') .slice (k-1, m.length + k-1) [i]). join ('')

Demo di CSSDeck

Disebut dengan:

waspadai 'rumah', 2

isvxn


Apakah Anda membaca seluruh pertanyaan, karena secara jelas menyatakan bahwa Anda tidak diperbolehkan "menggunakan konstanta yang disematkan dalam kode Anda"?
core1024
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.