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.

BrunoJ
sumber
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*-}%
aditsu berhenti karena SE adalah JAHAT
sumber
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)

Willem
sumber
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"
core1024
sumber
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.

BeetDemGuise
sumber
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"
gxtaillon
sumber
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

ISNIT
sumber
Apakah Anda membaca seluruh pertanyaan, karena secara jelas menyatakan bahwa Anda tidak diperbolehkan "menggunakan konstanta yang disematkan dalam kode Anda"?
core1024