Criptografia de janela PI


13

Este é um método simples de criptografia que usa dígitos PI para codificar uma mensagem; o método é simples:

A chave é apenas um número inteiro positivo que indica onde a janela é iniciada:

Dada uma cadeia de caracteres para criptografar, contendo apenas letras minúsculas, sem espaços, você obtém seu comprimento e, em seguida, encontra o N-ésimo dígito do PI e, em seguida, muda cada letra para a direita pela quantidade indicada pelo dígito.

Por exemplo, se a chave é 2e quero codificar house, pego uma janela de 5 dígitos do segundo: 14159e então ela se torna:

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

a.- Seu programa / função / algoritmo receberá dois parâmetros, uma sequência composta apenas de letras minúsculas sem espaços e a chave, que será apenas um número inteiro positivo entre 1 (1 refere-se a 3) e 1000, o que poderia ser mais ou menos, pois não tenho certeza de quanto tempo leva para calcular o PI com a precisão, porque:

b.- Você deve calcular o PI por conta própria no código, aqui está uma página interessante para comparar com: Dia do Pi . A entrada nunca deve permitir que você calcule o PI além dos 1000 dígitos, o que significa que o comprimento (mensagem) + chave <= 1000.

Ao calcular o Pi, quero dizer não codificá-lo em seu código (bobagem para um código de golfe), nem usar qualquer constante incorporada em seu código, nem nenhuma identidade trigonométrica (2 * acos (0)) nem qualquer referência na web.

c.- A saída será apenas a string criptografada.

Esta é uma questão de código de golfe, código mais curto ganha!

Aceitarei a resposta vencedora em 14 de julho de 2014.


1
O que acontece quando as letras passam do final do alfabeto? Ocorre uma volta ao início do alfabeto ou algo mais?
Digital Trauma

1
Sim, você apenas começa do zero.
brunoJ

6
O que conta como "calcule-se"? ArcCos(-1)?
Martin Ender

1
Expliquei melhor o que queria dizer calculando você mesmo e apontei que 3 é o primeiro dígito.
brunoJ

1
Isso realmente parece um algoritmo de criptografia realmente inteligente, por que isso não é amplamente usado (exceto com uma constante mais complicada como e ^ pi ou algo menos reconhecível)?
ASKASK

Respostas:


3

CJam - 51

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

Exemplo de entrada:

zebra
20

Resultado:

dkdxe

Isso funciona para (comprimento da string) + chave <= 2000, mas é bastante lento para o intérprete online (ainda rápido com o interpretador java).

Aqui está uma versão que funciona até 200 e você pode tentar em http://cjam.aditsu.net/ sem esperar muito:

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

5

Python - 370

Ok, bom, finalmente consegui trabalhar com o pi graças ao link1 e 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

Exemplo de saída:

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

e outro:

Wimt fcy d dnyh uhkvkv qhvadil   

>>> f ('Esta foi uma mensagem muito secreta', 1)


1

JavaScript - 167 173 176

Agradecimentos a Michael pela representação inteligente dos poderes de 16.

Isso pode calcular o PI até o 16º 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}

O caso de teste:

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

Que tal m=1e em m<<=4vez de m='0x1'e m+=0? Salva 3 bytes.
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])))])

A maior parte da versão golfada é fácil de ler e entender. A linha final é não destruída abaixo:

# 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: simplificou a aritmética do meu módulo.

EDIT # 2: refatorou a fórmula BBP.


0

Haskell - 265 267 bytes (sem 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

pé uma versão em golfe do algoritmo que pode ser encontrada em http://rosettacode.org/wiki/Pi#Haskell

e é a função de codificação:

λ> e 2 "house"
"isvxn"

Não circula se um índice estiver fora do alfabeto em minúsculas. Isso significa que alguns outros caracteres podem escorregar na cadeia codificada:

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

Infelizmente, leva alguns segundos com deslocamentos maiores que 10 000para calcular a saída. Felizmente, ao usar o mesmo deslocamento várias vezes, os dígitos precisam ser calculados apenas na primeira vez.

Bônus - Decodificação

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

Novamente, se testarmos com isvxn:

λ> d 2 "isvxn"
"house"

Cometeu um erro de digitação na sua seção de bônus. d 2 "isvsn"deve serd 2 "isvxn"
Spedwards

Fixo. Obrigado por perceber.
gxtaillon

0

CoffeeScript - 148 caracteres / bytes

Meu primeiro código Golf

Infelizmente, ele não suporta quebra automática (então az acabaria sendo pontuação)

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 ('')

Demonstração no CSSDeck

Chamado com:

alerta e 'casa', 2

isvxn


Você leu toda a pergunta, pois afirma claramente que você não tem permissão para "usar nenhuma constante incorporada no seu código"?
core1024
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.