Cifrado de ventana PI

13

Este es un método de encriptación simple que utiliza dígitos PI para codificar un mensaje, el método es simple:

La clave es solo un número entero positivo que indica dónde comienza la ventana:

Dada una cadena para encriptar, que contiene solo letras minúsculas, sin espacios, toma su longitud, luego encuentra el enésimo dígito de PI y luego procede a desplazar cada letra a la derecha por la cantidad indicada por el dígito.

Por ejemplo, si la clave es 2y quiero codificar house, tomo una ventana de 5 dígitos del segundo: 14159y luego se convierte en:

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

a.- Su programa / función / algoritmo recibirá dos parámetros, una cadena compuesta solo de letras minúsculas sin espacios y la clave, que será solo un entero positivo entre 1 (1 se refiere a 3) y 1000, que podría ser más o menos, ya que no estoy seguro de cuánto tiempo lleva calcular PI con dicha precisión porque:

b.- Debe calcular PI usted mismo en su código, aquí hay una página web ordenada para comparar con: Pi Day . La entrada nunca debe hacer que calcule PI más allá de los 1000 dígitos, lo que significa que la longitud (mensaje) + tecla <= 1000.

Al computar Pi, me refiero a no codificarlo en su código (tonto para un código de golf) ni usar ninguna constante incrustada en su código ni ninguna identidad trigonométrica (2 * acos (0)) ni ninguna referencia web.

c.- La salida será solo la cadena encriptada.

Esta es una pregunta de código de golf, ¡el código más corto gana!

Aceptaré la respuesta ganadora el 14 de julio de 2014.

BrunoJ
fuente
1
¿Qué sucede cuando las letras se desplazan más allá del final del alfabeto? ¿Se produce una vuelta al principio del alfabeto o algo más?
Trauma digital
1
Sí, solo comienzas desde el principio.
BrunoJ
66
¿Qué cuenta como "cómprate tú mismo"? ArcCos(-1)?
Martin Ender
1
Le expliqué mejor lo que quería decir al calcularlo usted mismo y señalé que 3 es el primer dígito.
BrunoJ
1
Esto en realidad parece un algoritmo de cifrado realmente inteligente, ¿por qué no se usa ampliamente (excepto con una constante más complicada como e ^ pi o algo menos reconocible)?
ASKASK

Respuestas:

3

CJam - 51

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

Entrada de ejemplo:

zebra
20

Salida:

dkdxe

Esto funciona para (longitud de cadena) + tecla <= 2000, pero es bastante lento para el intérprete en línea (todavía rápido con el intérprete de Java).

Aquí hay una versión que funciona hasta 200 y puede probarla en http://cjam.aditsu.net/ sin esperar demasiado:

l_,li(2e3,-2%{2+_2/@*\/2e200+}*Ab><]z{~+_'z>26*-}%
aditsu renunció porque SE es MALO
fuente
5

Python - 370

Ok, agradable, finalmente conseguí que la cosa pi funcionara gracias a link1 y 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

Salida de ejemplo:

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

y otro:

Wimt fcy d dnyh uhkvkv qhvadil   

>>> f ('Este fue un mensaje muy secreto', 1)

Willem
fuente
1

JavaScript - 167 173 176

Gracias a Michael por la inteligente representación de los poderes de 16.

Esto puede calcular PI hasta el decimosexto dígito.

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}

El caso de prueba:

> e("house",2)
"isvxn"
core1024
fuente
¿Qué pasa con m=1y en m<<=4lugar de m='0x1'y m+=0? Ahorra 3 bytes.
Michael M.
1

Pitón - 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])))])

La mayor parte de la versión de golf es fácil de leer y comprender. La línea final está sin golf debajo:

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

EDITAR # 1: simplificó la aritmética de mi módulo.

EDITAR # 2: refactorizó la fórmula BBP.

BeetDemGuise
fuente
0

Haskell - 265 267 bytes (sin E / S)

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

pes una versión de golf del algoritmo que se puede encontrar en http://rosettacode.org/wiki/Pi#Haskell

e es la función de codificación:

λ> e 2 "house"
"isvxn"

No se repite si un índice está fuera del alfabeto en minúsculas. Esto significa que algunos otros caracteres pueden deslizarse en la cadena codificada:

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

Desafortunadamente, lleva varios segundos con desplazamientos mayores que 10 000calcular la salida. Afortunadamente, cuando se usa el mismo desplazamiento varias veces, los dígitos solo deben calcularse la primera vez.

Bonus - Decodificación

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

De nuevo si probamos con isvxn:

λ> d 2 "isvxn"
"house"
gxtaillon
fuente
Hizo un error tipográfico en su sección de bonificación. d 2 "isvsn"debería serd 2 "isvxn"
Spedwards
Fijo. Gracias por notarlo.
gxtaillon
0

CoffeeScript - 148 caracteres / bytes

Mi primer código de golf

Desafortunadamente, no admite el ajuste (por lo tanto, az terminaría siendo puntuación)

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

Demostración en CSSDeck

Llamado con:

alerta e 'casa', 2

isvxn

ISNIT
fuente
¿Leyó toda la pregunta, ya que establece claramente que no está permitido "usar ninguna constante incrustada en su código"?
core1024