Chiffrement informatique

14

Introduction:

J'ai des tas de chiffrements différents stockés dans un document que j'ai compilé quand j'étais enfant, j'ai choisi quelques-uns de ceux que je pensais être les mieux adaptés aux défis (pas trop triviaux et pas trop difficiles) et les ai transformés en défis. La plupart d'entre eux sont toujours dans le bac à sable, et je ne sais pas encore si je vais tous les poster, ou seulement quelques-uns. Mais voici le premier à commencer.


Un chiffrement informatique chiffrera le texte donné en groupes de caractères «aléatoires» d'un donné length. Si un tel groupe contient un chiffre, il utilisera ce chiffre pour indexer dans son propre groupe le caractère chiffré. Si aucun chiffre n'est présent dans le groupe, cela signifie que le premier caractère est utilisé.

Par exemple, disons que nous voulons chiffrer le texte this is a computer cipheravec une longueur donnée de 5. Il s'agit d'une sortie potentielle (remarque: les nombres sont indexés 1 dans l'exemple ci-dessous):

t     h     i     s     i     s     a     c     o     m     p     u     t     e     r     c     i     p     h     e     r       (without spaces of course, but added as clarification)
qu5dt hprit k3iqb osyw2 jii2o m5uzs akiwb hwpc4 eoo3j muxer z4lpc 4lsuw 2tsmp eirkr r3rsi b5nvc vid2o dmh5p hrptj oeh2l 4ngrv   (without spaces of course, but added as clarification)

Prenons quelques groupes comme exemples pour expliquer comment déchiffrer le groupe:

  • qu5dt: Ce groupe contient un chiffre 5, de sorte que le 5 (1-indexé) caractère de ce groupe est le caractère utilisé pour le texte déchiffré: t.
  • hprit: Ce groupe ne contient pas de chiffres, de sorte que le premier caractère de ce groupe est utilisé implicitement pour le texte déchiffré: h.
  • osyw2: Ce groupe contient un chiffre 2, de sorte que le (1-indexé) 2e caractère de ce groupe est le caractère utilisé pour le texte déchiffré: s.

Défi:

Étant donné un entier lengthet une chaîne word_to_encipher, sortez une chaîne chiffrée aléatoire comme décrit ci-dessus.

Vous n'avez qu'à chiffrer étant donné le lengthet word_to_encipher, donc pas besoin de créer un programme / fonction de déchiffrement également. Cependant, je pourrais faire un défi de partie 2 pour le déchiffrement à l'avenir.

Règles du défi:

  • Vous pouvez supposer que le lengthsera dans la plage [3,9].
  • Vous pouvez supposer que le word_to_enciphertest ne contiendra que des lettres.
  • Vous pouvez utiliser des minuscules ou des majuscules (veuillez indiquer celui que vous avez utilisé dans votre réponse).
  • Vos sorties, chaque groupe et les positions des chiffres dans un groupe (le cas échéant) doivent être uniformément aléatoires . Ainsi, toutes les lettres aléatoires de l'alphabet ont les mêmes chances de se produire; la position de la lettre chiffrée dans chaque groupe a les mêmes chances de se produire; et la position du chiffre a les mêmes chances de se produire (sauf lorsqu'il s'agit du premier caractère et qu'aucun chiffre n'est présent; et il ne peut évidemment pas être à la même position que le caractère chiffré).
  • Vous êtes également autorisé à utiliser des chiffres indexés de 0 au lieu de 1 indexés. Veuillez indiquer laquelle des deux vous avez utilisée dans votre réponse.
  • Le chiffre 1(ou 0lorsqu'il est indexé 0) ne sera jamais présent dans la sortie. Ce b1ndhn'est donc pas un groupe valide pour chiffrer le caractère «b». Toutefois, b4tbwest valable, où les 4chiffre le bà la position 4 (1-indexé), et les autres personnages b, t, wsont aléatoires (qui par coïncidence contient également un b). D' autres groupes possibles valides de length5 à Chiffrer le caractère « b » sont: abcd2, ab2de, babbk, hue5b, etc.

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues non-golfeur de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse avec des règles d'E / S par défaut , vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés et des programmes complets de type retour. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code (par exemple TIO ).
  • De plus, l'ajout d'une explication à votre réponse est fortement recommandé.

Cas de test:

Input:
 Length:           5
 Word to encipher: thisisacomputercipher
Possible output:
 qu5dthpritk3iqbosyw2jii2om5uzsakiwbhwpc4eoo3jmuxerz4lpc4lsuw2tsmpeirkrr3rsib5nvcvid2odmh5phrptjoeh2l4ngrv

Input:
 Length:           8
 Word to encipher: test
Possible output:
 ewetng4o6smptebyo6ontsrbtxten3qk

Input:
 Length:           3
 Word to encipher: three
Possible output:
 tomv3h2rvege3le
Kevin Cruijssen
la source
2
Comment signifie "uniforme"
l4m2
@ l4m2 Qu'il y ait une chance égale pour n'importe quelle sortie. Ainsi, toutes les lettres aléatoires de l'alphabet ont les mêmes chances de se produire; la position de la lettre chiffrée dans chaque groupe a les mêmes chances de se produire; et la position du chiffre a les mêmes chances de se produire (sauf lorsqu'il s'agit du premier caractère et qu'aucun chiffre n'est présent, et également pas à la même position que le caractère chiffré).
Kevin Cruijssen
Alors abcd2, ab2de, babbktout de même? Est également b1akkvalide?
l4m2
@ l4m2 Oui, les trois sont des sorties possibles chiffrant le caractère 'b'. Quant à b1akkmoi, je dirais non. Le modifiera dans la description du défi pour clarifier. Si le premier caractère est le chiffre chiffré, aucun chiffre ne doit être présent.
Kevin Cruijssen
1
Par exemple, lorsque length = 3, char = "a"; La forme "a??"a 676 résultats possibles, mais "1a?", "?a1", "2?a", "?2a", a only104 résultats. Donc, si j'essaye de choisir un résultat parmi tous ces 780 résultats, la distribution de la "position de la lettre chiffrée" est 13: 1: 1, pas 1: 1: 1. Et je considérerais cela comme un fonctionnement "uniformément aléatoire".
tsh

Réponses:

3

Pyth, 22 octets

smsXWJOQXmOGQJdO-UQJJz

Essayez-le en ligne.

Utilise l'index en minuscules et zéro.

Explication

Algorithme très simple.

                           Implicit: read word in z
                           Implicit: read number in Q
 m                   z     For each char d in z:
      OQ                     Choose a number 0..Q-1
     J                       and call it J.
         m  Q                Make an array of Q
          OG                 random letters.
        X     d              Place d in this string
             J               at position J.
    W                        If J is not 0,
   X                J        place J in this string
               O             at a random position from
                 UQ          0..Q-1
                -  J         except for J.
  s                          Concatenate the letters.
s                          Concatenate the results.
PurkkaKoodari
la source
5

Perl 6 , 125 octets

->\n{*.&{S:g{.}=(65..90)>>.chr.roll(n).join.subst(/./,$/,:th($!=roll 1..n:)).subst(/./,$!,:th($!-1??(^n+1$!).roll!!n+1))}}

Essayez-le en ligne!

Prend l'entrée et la sortie en majuscules. Prend les entrées au curry, comme f(n)(string). Utilise 1 indexation.

Explication:

->\n{*.&{ ...  }}   # Anonymous code block that takes a number n and returns a function
     S:g{.}=        # That turns each character of the given string into
                          .roll(n)      # Randomly pick n times with replacement
            (65..90)>>.chr              # From the uppercase alphabet
                                  .join # And join
            .subst(                         ) # Then replace
                   /./,  ,:th($!=roll 1..n:)  # A random index (saving the number in $!)
                       $/               # With the original character
            .subst(                )    # Replace again
                   /./,$!,:th( ... )    # The xth character with $!, where x is:
                           $!-1??          # If $! is not 1
                                 (^n+1$!).roll       # A random index that isn't $!
                                               !!n+1  # Else an index out of range
Jo King
la source
4

Python 2 , 187 177 176 156 154 148 octets

lambda l,s:''.join([chr(choice(R(65,91))),c,`n`][(j==n)-(j==i)*(n>0)]for c in s for n,i in[sample(R(l),2)]for j in R(l))
from random import*
R=range

Essayez-le en ligne!

Utilise des lettres majuscules et des nombres indexés 0.

-3 octets, merci à Kevin Cruijssen

TFeld
la source
@KevinCruijssen Merci :)
TFeld
Que veut sample(R(l),2)[::1|-(random()<.5)]dire?
l4m2
@ l4m2 Il prend 2 nombres range(l)et les mélange. Mais apparemment, l'échantillon ne garantit pas la commande, il n'est donc pas nécessaire :)
TFeld
Vous ne pouvez pas supprimer les parenthèses autour (j==i)*(n>0)? La multiplication a la priorité de l'opérateur sur la soustraction, n'est-ce pas?
Kevin Cruijssen
1
@KevinCruijssen Ouais, j'ai oublié de les supprimer, quand j'ai eu des problèmes
TFeld
3

JavaScript (Node.js) , 135 octets

n=>f=([c,...s])=>c?(g=n=>n?g(--n)+(n-p?n-q|!p?(r(26)+10).toString(36):p:c):'')(n,r=n=>Math.random()*n|0,p=r(n),q=r(n-1),q+=q>=p)+f(s):s

Essayez-le en ligne!

Merci Arnauld pour 1B

l4m2
la source
3

R , 134 132 123 octets

function(S,n,s=sample)for(k in utf8ToInt(S)){o=k+!1:n
P=s(n,1)
o[-P]=s(c(P[i<-P>1],s(17:42,n-1-i,T)))+48
cat(intToUtf8(o))}

Essayez-le en ligne!

Prend des lettres majuscules.

Explication de l'ancien code (essentiellement la même approche):

function(S,n){s=sample				# alias
K=el(strsplit(S,""))				# split to characters
o=1:n						# output array
for(k in K){					# for each character in the string
P=s(n,1)					# pick a Position for that character
o[-P]=						# assign to everywhere besides P:
      s(					# a permutation of:
	c(P[i<-P>1],				# P if it's greater than 1
		s(letters,n-1-i,T)))		# and a random sample, with replacement, of lowercase letters
o[P]=k						# set k to position P
cat(o,sep="")}}					# and print
Giuseppe
la source
2

Java (JDK) , 193 octets

s->n->s.flatMap(c->{int a[]=new int[n],i=n,x=0;for(;i-->0;)a[i]+=Math.random()*26+97;a[i+=Math.random()*n+1]=c;x+=Math.random()*~-n;if(i>0)a[x<i?x:x+1]=48+i;return java.util.Arrays.stream(a);})

Essayez-le en ligne!

  • L'index est basé sur 0.
  • Cette entrée utilise un IntStream(obtenu String::chars) comme entrée, ainsi qu'un nombre et renvoie un autreIntStream .
  • Les conversions de doubleà intsont inutiles à cause du +=hack.
Olivier Grégoire
la source
2

Japt , 29 octets

;£=VöJ;CöV hUÎX hUÅÎUÎ?UÎs:Cö

Essayez-le en ligne!

Zéro indexé.

Explication:

;                                :Set C = [a...z]
 £                               :For each character of the input:
  =VöJ;                          : Get two different random indexes from [0,length)
       CöV                       : Get 5 random letters
           hUÎX                  : Replace one at random with the character from the input
                hUÅÎ             : Replace a different random character with:
                    UÎ?          :  If the input character was not placed at 0:
                       UÎs       :   The index of the input character
                          :      :  Otherwise:
                           Cö    :   A random letter
                                 :Implicitly join back to a string
Kamil Drakari
la source
2

C, 115 octets

g(_,n)char*_;{int i=rand(),j=i%~-n,k=0;for(i%=n;k<n;k++)putchar(k-i?!i|i<k^k-j?rand()%26+97:48+i:*_);*++_&&g(_,n);}

Essayez-le en ligne!

Index 0, minuscule.

Légèrement non golfé et étendu:

g(char*_,int n) {
    int i = rand(), j = i%(n-1), k = 0;
    for(i = i%n; k<n; k++)
        putchar(k!=i ? i!=0 || k==j + (k>i)
                          ? rand()%26 + 'A'
                          : i + '0')
                    : *_);
    if (*++_!=0) g(_,n);
}

Le code devrait être assez simple. Les deux aléas i, jgénérés en un seul rand()appel sont bons car indépendants puisque gcd ( n, ~-n) = 1 et RAND_MAXest grand.

attinat
la source
1
Bienvenue chez PPCG! :)
Shaggy
1

Nettoyer , 256 octets

import StdEnv
s::!Int->Int
s _=code {
ccall time "I:I"
ccall srand "I:I"
}
r::!Int->Int
r _=code {
ccall rand "I:I"
}
$n|s 0<1#k=map\e.r e rem n
=flatten o map\c.hd[map(\i|i==x=c=toChar if(i==y&&x>0)(x+48)(r i rem 26+97))[0..n-1]\\x<-k[0..]&y<-k[0..]|x<>y]

Essayez-le en ligne!

Choisit:

  • un aléatoire x(position du personnage dans le segment)
  • un aléatoire yqui n'est pas égal à x(position du chiffre dans le segment)
  • une lettre minuscule aléatoire pour chaque position non égale xet non égale à ymoins que xzéro
Οurous
la source
1

JavaScript, 134 octets

l=>w=>w.replace(/./g,c=>eval("for(s=c;!s[l-1]||s[t?t-1||9:0]!=c;t=s.replace(/\\D/g,''))s=(p=Math.random()*36**l,p-p%1).toString(36)"))

Essayez-le en ligne!

Cette réponse a choisi la chaîne codée parmi toutes les chaînes codées possibles uniformément. Il est donc plus possible de faire de la lettre encodée la première.

tsh
la source
1

C # (Visual C # Interactive Compiler) , 171 octets

s=>n=>{var r=new Random();return s.SelectMany(c=>{int i=r.Next(n),j=r.Next(n-1);j+=j<i?0:1;return new int[n].Select((_,k)=>(char)(i==k?c:j==k&i>0?i+49:r.Next(26)+97));});}

Essayez-le en ligne!

Explication...

// s is the input string
// n is the input length
s=>n=>{
  // we need to create an instance
  // of Random and use throughout
  var r=new Random();
  // iterate over s, each iteration
  // returns an array... flatten it
  return s.SelectMany(c=>{
    // i is the position of the letter
    // j is the position of the number
    int i=r.Next(n), j=r.Next(n-1);
    // ensure i and j are different
    j+=j<i?0:1;
    // create an iterable of size n
    return new int[n]
      // iterate over it with index k
      .Select((_,k)=>(char)(
        // return the letter
        i==k?c:
        // return the number
        j==k&i>0?i+49:
        // return a random letter
        r.Next(26)+97)
      );
  });
}
dana
la source
1

Fusain , 35 30 octets

NθFS«≔‽θη≔∧η‽Φθ⁻κηζFθ≡κζIηηι‽β

Essayez-le en ligne! Le lien est vers la version détaillée du code. 0 indexé. Explication:

Nθ

Saisissez la longueur.

FS«

Saisissez le mot et bouclez sur les caractères.

≔‽θη

Choisissez une position aléatoire pour la lettre déchiffrée.

≔∧η‽Φθ⁻κηζ

Choisissez une position aléatoire différente pour le chiffre, sauf si la lettre est à la position 0, auquel cas placez également le chiffre à la position 0.

Fθ≡κ

Faites une boucle pour chaque caractère de sortie et activez la position.

ζIη

S'il s'agit de la position du chiffre, affichez la position de la lettre déchiffrée.

ηι

Mais si c'est la position de la lettre déchiffrée, sortez la lettre. Cela a priorité sur la position du chiffre car le charbon de bois prend la dernière entrée si plusieurs boîtiers de commutation ont la même valeur.

‽β

Sinon, affichez une lettre aléatoire.

Neil
la source
0

05AB1E , 26 octets

ε²Ý¨Ω©A.r²£Šǝ®Āi®²Ý¨®KΩǝ]J

0 indexé.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

ε            # Map over the characters of the first (implicit) input-string:
 ²Ý¨         #  Create a list in the range [0, second input)
    Ω        #  Get a random item from this list
     ©       #  Store it in the register (without popping)
 A           #  Push the lowercase alphabet
  .r         #  Shuffle it
    ²£       #  Leave only the first second input amount of characters
      Š      #  Triple swap, so the stack order becomes:
             #  random index; random string; map-character
       ǝ     #  Insert the map-character at this random index into the random string
 ®Āi         #  If the random index was NOT 0:
    ®        #   Push the random index
    ²Ý¨      #   Push the list in the range [0, second input) again
       ®K    #   Remove the random index from this list
         Ω   #   Get a random item from this list
          ǝ  #   Insert the first random index at the second random index into the string
]            # Close both the if-else and map
 J           # Join all strings together (and output implicitly)
Kevin Cruijssen
la source