Contexte
Un tampon à usage unique est une forme de cryptage qui s'est avérée impossible à casser s'il est utilisé correctement.
Le chiffrement est effectué en prenant un texte en clair (composé uniquement de lettres AZ) et en générant une chaîne aléatoire sur la même longueur (également uniquement des lettres). Cette chaîne sert de clé. Chaque caractère du texte en clair est ensuite associé au caractère correspondant dans la clé. Le texte chiffré est calculé comme suit: Pour chaque paire, les deux caractères sont convertis en nombres (A = 0, B = 1, ... Z = 25). Les deux nombres sont ajoutés modulo 26. Ce nombre est reconverti en caractère.
Le déchiffrement est exactement le contraire. Les caractères du texte chiffré et de la clé sont appariés et convertis en nombres. La clé est ensuite soustraite du module de texte chiffré 26, et le résultat est reconverti en un caractère AZ.
Le défi
Votre défi est d'écrire le programme le plus court possible qui peut à la fois crypter et décrypter un pad à usage unique.
Sur la première ligne d'entrée (vers STDIN), il y aura soit le mot "ENCRYPT" soit le mot "DECRYPT".
Si le mot est crypté, la ligne suivante sera le texte en clair. Votre programme doit produire deux lignes (vers STDOUT), la première étant la clé et la seconde le texte chiffré.
Si le mot est déchiffré, votre programme recevra deux lignes d'entrée supplémentaires. La première ligne sera la clé et la deuxième ligne sera le texte chiffré. Votre programme doit sortir une ligne, qui sera le texte en clair qui a été déchiffré.
Le texte en clair, le texte chiffré et la clé doivent toujours être constitués de lettres majuscules AZ. Ils seront toujours une seule ligne et ne contiendront aucun espace.
La clé doit toujours être aléatoire. Aucune grande partie de celui-ci ne doit se répéter entre les exécutions et aucun motif ne doit être trouvé dans le texte.
Deux exemples simples:
ENCRYPT
HAPPYBIRTHDAY
>ABKJAQLRJESMG
>HBZYYRTICLVME
DECRYPT
ABKJAQLRJESMG
HBZYYRTICLVME
>HAPPYBIRTHDAY
Le >
représente les lignes qui sont sorties, vous n'avez donc pas besoin d'imprimer ce symbole comme sortie.
la source
/dev/random
,haveged
), chiffrer en xorant les ords avec les octets et déchiffrer en les xorant avec la clé. gist.github.com/5078264 la clé ou l'aléatoire peut être lu depuis stdin, le message ou le cryptogramme peut être un argument de nom de fichier./dev/hwrng
, au lieu d'utiliser un pseudo aléatoire (ce qui le rend techniquement cassé))Réponses:
GolfScript, 53 caractères
C'est une tâche pour laquelle GolfScript semble à peu près parfaitement adapté.
Pour garder le code court, j'utilise le même code à la fois pour le chiffrement et le déchiffrement: pour déchiffrer, je soustrais la clé du texte chiffré, tandis que pour le chiffrement, je génère d'abord un texte chiffré aléatoire, puis j'en soustrais le texte en clair. Même ainsi, le code supplémentaire pour implémenter le mode de cryptage prend un peu plus de la moitié de la longueur du programme.
Version dé-golfée avec commentaires:
la source
Ruby (
200185)échantillon exécute + wc:
la source
s[k=(p=f).map{rand 26}],r[k,p,:-]
devrait être écrits[k=f.map{rand 26}],r[k,$_,:-]
$_
la dernière ligne lue pargets
.f
fait aussi.scan(/./).map{|b|b.ord-65}
après avoir lu une ligne.Haskell, 203 caractères
Exemple:
la source
Perl,
220171 caractèresExemple d'exécution:
Remarque: au moins lorsque je l'exécute, "Appuyez sur n'importe quelle touche pour continuer ..." est ajouté à la fin de la dernière sortie. J'espère que ça va, car cela ne fait pas partie du programme. Sinon, je peux le faire apparaître sur la ligne suivante.
Ceci est mon premier vrai programme en Perl et mon tout premier golf, donc j'apprécierais vraiment les conseils. De plus, j'ai trouvé
/(.)/g
sur Internet, mais je n'ai aucune idée de comment cela fonctionne (est-ce une expression régulière? Je ne les ai pas encore apprises). Quelqu'un peut-il me l'expliquer?EDIT: Merci à Ilmari Karonen de m'avoir aidé avec les regexps, j'ai utilisé mes nouvelles connaissances pour sauver 7 personnages!
Version étendue, légèrement lisible:
la source
/(.)/g
c'est une expression rationnelle. Vous voudrez certainement les apprendre si vous voulez jouer au golf Perl. perldoc.perl.org/perlre.html n'est pas un mauvais point de départ.Python -
304295Je crois que cela correspond exactement aux spécifications
(y comprisCela ne valide pas l'entrée, donc je pense que cela produira simplement une sortie poubelle si vous lui donnez des caractères en dehors de'>'
au début des invites d'entrée.)[A-Z]
. Il vérifie également uniquement la première lettre de la commande d'entrée. Tout ce qui commence parD
entraînera un déchiffrement et toute autre chose entraînera un chiffrement.la source
>
, je l'utilisais simplement pour montrer quelles lignes étaient sorties. Vous n'avez pas à les implémenter.C ++ -
220241 caractères, 4 lignesEdit 1- La bibliothèque standard MSVS semble inclure beaucoup de fichiers inutiles, ce qui signifie qu'ios avait toutes les inclusions dont j'avais besoin, mais cela ne fonctionnait pas avec d'autres compilateurs. Ios modifié pour les fichiers réels que les fonctions nécessaires apparaissent dans cstdlib et cstdio. Merci à Ilmari Karonen de l'avoir signalé.
la source
g++ otp.cpp
ditotp.cpp: In function ‘int main()’: otp.cpp:3: error: ‘scanf’ was not declared in this scope otp.cpp:3: error: ‘rand’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope
Python - 270
Exemple de sortie:
Nombre de caractères:
la source
J: 94 octets
Tous les espaces blancs nécessaires ont été comptés.
Version commentée:
la source
C # (
445416)J'ai oublié Aggregate. Coupez un peu.
Assez joué au golf:
}
Golfé:
la source
C (159 + 11 pour les drapeaux du compilateur)
Golfé:
Non golfé:
Compilez avec
-Dg=gets(s)
.Exemple:
la source
JavaScript 239
Usage:
la source
Ruby -
184179177 caractèresExécutez-le comme ceci:
$ ruby pad-lock.rb
Voici la version non golfée si quelqu'un est intéressé (elle n'est pas tout à fait à jour avec celle du golf)
la source