Chiffrement de fenêtre PI


13

Il s'agit d'une méthode de cryptage simple qui utilise des chiffres PI pour coder un message, la méthode est simple:

La clé est juste un entier positif qui indique où commence la fenêtre puis:

Étant donné une chaîne à chiffrer, ne contenant que des lettres minuscules, pas d'espaces, vous prenez sa longueur, puis vous trouvez le Nième chiffre de PI, puis vous déplacez chaque lettre vers la droite pour le montant indiqué par le chiffre.

Par exemple, si la clé est 2et que je veux encoder house, je prends une fenêtre de 5 chiffres à partir du second: 14159puis ça devient:

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

a.- Votre programme / fonction / algorithme recevra deux paramètres, une chaîne composée uniquement de lettres minuscules sans espaces et la clé, qui sera juste un entier positif entre 1 (1 fait référence à 3) et 1000, ce qui pourrait être plus ou moins car je ne sais pas combien de temps faut-il pour calculer PI avec cette précision parce que:

b.- Vous devez calculer PI vous-même dans votre code, voici une page Web soignée à comparer avec: Pi Day . L'entrée ne devrait jamais vous faire calculer PI au-delà des 1000 chiffres, ce qui signifie que la longueur (message) + clé <= 1000.

En calculant Pi, je ne veux pas le coder dans votre code (idiot pour un code golf) ni utiliser aucune constante intégrée dans votre code ni aucune identité trigonométrique (2 * acos (0)) ni aucune référence Web.

c.- La sortie sera juste la chaîne cryptée.

Ceci est une question de code de golf, un code plus court gagne!

J'accepterai la réponse gagnante le 14 juillet 2014.


1
Que se passe-t-il lorsque les lettres sont décalées après la fin de l'alphabet? Y a-t-il un retour au début de l'alphabet ou autre chose?
Digital Trauma

1
Oui, vous recommencez depuis le début.
BrunoJ

6
Qu'est-ce qui compte comme «calculez-vous»? ArcCos(-1)?
Martin Ender

1
J'ai mieux expliqué ce que je voulais dire en le calculant vous-même et j'ai souligné que 3 est le premier chiffre.
BrunoJ

1
Cela ressemble en fait à un algorithme de cryptage vraiment intelligent, pourquoi n'est-il pas largement utilisé (sauf avec une constante plus compliquée comme e ^ pi ou quelque chose de moins reconnaissable)?
ASKASK

Réponses:


3

CJam - 51

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

Exemple d'entrée:

zebra
20

Production:

dkdxe

Cela fonctionne pour (longueur de chaîne) + clé <= 2000, mais est assez lent pour l'interpréteur en ligne (toujours rapide avec l'interpréteur java).

Voici une version qui fonctionne jusqu'à 200 et vous pouvez essayer sur http://cjam.aditsu.net/ sans attendre trop longtemps:

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

5

Python - 370

Ok, nice, a finalement obtenu la chose pi travailler avec grâce à link1 et lien2 .

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

Exemple de sortie:

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

et un autre:

Wimt fcy d dnyh uhkvkv qhvadil   

>>> f ('C'était un message très secret', 1)


1

JavaScript - 167 173 176

Merci à Michael pour la représentation intelligente des pouvoirs de 16.

Cela peut calculer PI jusqu'au 16ème chiffre.

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}

Le cas de test:

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

Qu'en est-il m=1et m<<=4au lieu de m='0x1'et m+=0? Enregistre 3 octets.
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])))])

La plupart de la version golfée est facile à lire et à comprendre. La dernière ligne n'est pas golfée ci-dessous:

# 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: simplification de l'arithmétique de mon module.

EDIT # 2: refactorisé la formule BBP.


0

Haskell - 265 267 octets (pas d'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

pest une version golfée de l'algorithme qui peut être trouvée à http://rosettacode.org/wiki/Pi#Haskell

e est la fonction d'encodage:

λ> e 2 "house"
"isvxn"

Il ne fait pas de boucle si un index est en dehors de l'alphabet minuscule. Cela signifie que d'autres caractères peuvent glisser dans la chaîne codée:

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

Malheureusement, cela prend plusieurs secondes avec des décalages supérieurs à 10 000pour calculer la sortie. Heureusement, lorsque vous utilisez le même décalage plusieurs fois, les chiffres ne doivent être calculés que la première fois.

Bonus - décodage

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

Encore une fois si nous testons avec isvxn:

λ> d 2 "isvxn"
"house"

Faites une faute de frappe dans votre section bonus. d 2 "isvsn"devrait êtred 2 "isvxn"
Spedwards

Fixé. Merci d'avoir remarqué.
gxtaillon

0

CoffeeScript - 148 caractères / octets

Mon tout premier Code Golf

Malheureusement, il ne prend pas en charge le wrapping (donc az finirait par être une ponctuation)

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

Démo sur CSSDeck

Appelé avec:

alerte e 'maison', 2

isvxn


Avez-vous lu toute la question, car elle indique clairement que vous n'êtes pas autorisé à "utiliser une constante intégrée dans votre code"?
core1024
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.