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.


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*-}%

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)


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"

¿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.


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"

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


¿Leyó toda la pregunta, ya que establece claramente que no está permitido "usar ninguna constante incrustada en su código"?
core1024
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.