Cifrado de la computadora


14

Introducción:

Tengo un montón de cifrados diferentes almacenados en un documento que una vez compilé cuando era niño, elegí algunos de los que pensé que eran los más adecuados para los desafíos (no demasiado triviales y no demasiado difíciles) y los transformé en desafíos. La mayoría de ellos todavía están en la caja de arena, y todavía no estoy seguro de si los publicaré todos, o solo unos pocos. Pero aquí está el primero de ellos para comenzar.


Un cifrado de computadora cifrará el texto dado en grupos de caracteres 'aleatorios' de un determinado length. Si dicho grupo contiene un dígito, usará ese dígito para indexar en su propio grupo para el carácter cifrado. Si no hay ningún dígito presente en el grupo, significa que se usa el primer carácter.

Por ejemplo, supongamos que queremos cifrar el texto this is a computer ciphercon una longitud determinada de 5. Esta es una salida potencial (nota: los números están indexados en 1 en el siguiente ejemplo):

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)

Tomemos algunos grupos como ejemplos para explicar cómo descifrar el grupo:

  • qu5dt: Este grupo contiene un dígito 5, por lo que el (1-indexada) quinto carácter de este grupo es el carácter utilizado para el texto descifrado: t.
  • hprit: Este grupo contiene ningún dígito, por lo que el primer carácter de este grupo se utiliza implícitamente el texto descifrado: h.
  • osyw2: Este grupo contiene un dígito 2, por lo que el (indexada 1) segundo carácter de este grupo es el carácter utilizado para el texto descifrado: s.

Desafío:

Dado un entero lengthy una cadena word_to_encipher, genera una cadena cifrada aleatoria como se describió anteriormente.

Solo tiene que cifrar dado el lengthy word_to_encipher, por lo que no es necesario crear un programa / función de descifrado también. Sin embargo, podría hacer un desafío de la parte 2 para descifrar en el futuro.

Reglas de desafío:

  • Puede suponer lengthque estará en el rango [3,9].
  • Puede suponer word_to_encipherque solo contendrá letras.
  • Puede usar minúsculas o mayúsculas (indique cuál ha utilizado en su respuesta).
  • Sus salidas, cada grupo y las posiciones de los dígitos en un grupo (si está presente) deben ser uniformemente al azar . Entonces, todas las letras aleatorias del alfabeto tienen la misma posibilidad de aparecer; la posición de la letra cifrada en cada grupo tiene la misma posibilidad de ocurrir; y la posición del dígito tiene la misma posibilidad de ocurrir (excepto cuando es el primer carácter y no hay ningún dígito presente; y obviamente no puede estar en la misma posición que el carácter cifrado).
  • También puede usar dígitos indexados 0 en lugar de 1 indexado. Indique cuál de los dos ha utilizado en su respuesta.
  • El dígito 1(o 0cuando está indexado a 0) nunca estará presente en la salida. Por b1ndhlo tanto, no es un grupo válido para cifrar el carácter 'b'. Sin embargo, b4tbwes válida, en donde los 4se cifra los ben la cuarta posición (1-indexada), y los otros personajes b, t, wson aleatorios (que casualmente también contiene una b). Otros grupos válidos posibles de length5 a cifrar el carácter 'b' son: abcd2, ab2de, babbk, hue5b, etc.

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de código de golf lo desalienten de publicar respuestas con idiomas que no sean de código. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Las reglas estándar se aplican a su respuesta con las reglas de E / S predeterminadas , por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados y programas completos de tipo retorno. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código (es decir, TIO ).
  • Además, se recomienda agregar una explicación para su respuesta.

Casos de prueba:

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

2
¿Qué significa "uniforme"?
l4m2

@ l4m2 Que hay una oportunidad igual para cualquier salida. Entonces, todas las letras aleatorias del alfabeto tienen la misma posibilidad de aparecer; la posición de la letra cifrada en cada grupo tiene la misma posibilidad de ocurrir; y la posición del dígito tiene la misma posibilidad de ocurrir (excepto cuando es el primer carácter y no hay ningún dígito presente, y tampoco en la misma posición que el carácter cifrado).
Kevin Cruijssen

Así abcd2, ab2de, babbktodos iguales? ¿También es b1akkválido?
l4m2

@ l4m2 Sí, las tres son salidas posibles que cifran el carácter 'b'. En cuanto a b1akkyo diría que no. Lo editará en la descripción del desafío para aclararlo. Si el primer carácter es el cifrado, no debe haber ningún dígito.
Kevin Cruijssen

1
Por ejemplo, cuando length = 3, char = "a"; La forma "a??"tiene 676 resultados posibles, pero "1a?", "?a1", "2?a", "?2a", tiene only104 resultados. Entonces, si estoy tratando de elegir un resultado de todos estos 780 resultados, la distribución de "posición de la letra cifrada" es 13: 1: 1, no 1: 1: 1. Y consideraría esto como un trabajo "uniformemente aleatorio".
tsh

Respuestas:


3

Pyth, 22 bytes

smsXWJOQXmOGQJdO-UQJJz

Pruébalo en línea.

Utiliza minúsculas y cero indexación.

Explicación

Algoritmo muy sencillo.

                           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.

5

Perl 6 , 125 bytes

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

Pruébalo en línea!

Toma entrada y salida en mayúsculas. Toma entrada curry, como f(n)(string). Utiliza 1 indexación.

Explicación:

->\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

4

Python 2 , 187 177 176 156 154 148 bytes

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

Pruébalo en línea!

Utiliza letras mayúsculas y números indexados a 0.

-3 bytes, gracias a Kevin Cruijssen


@KevinCruijssen Gracias :)
TFeld

Que sample(R(l),2)[::1|-(random()<.5)]significa
l4m2

@ l4m2 Toma 2 números range(l)y los baraja. Pero aparentemente la muestra no garantiza el pedido, por lo que no es necesaria :)
TFeld

¿No puedes quitar el paréntesis (j==i)*(n>0)? La multiplicación tiene prioridad de operador sobre la resta, ¿no?
Kevin Cruijssen

1
@KevinCruijssen Sí, olvidé eliminarlos, cuando tuve algunos problemas
TFeld


3

R , 134 132 123 bytes

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))}

Pruébalo en línea!

Toma letras mayúsculas.

Explicación del código antiguo (principalmente el mismo enfoque):

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

2

Java (JDK) , 193 bytes

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);})

Pruébalo en línea!

  • El índice está basado en 0.
  • Esta entrada utiliza un IntStream(conseguido String::chars) como entrada, así como un número y devuelve otroIntStream .
  • Los lanzamientos de doublea intson innecesarios debido al +=hack.

2

Japt , 29 bytes

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

Pruébalo en línea!

Indexado a cero.

Explicación:

;                                :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

2

C, 115 bytes

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);}

Pruébalo en línea!

0 indexado, en minúsculas.

Ligeramente sin golf y expandido:

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);
}

El código debería ser bastante sencillo. Los dos randoms i, jgenerados en una rand()llamada, son buenos como independientes ya que gcd ( n, ~-n) = 1 y RAND_MAXes grande.


1
Bienvenido a PPCG! :)
Shaggy

1

Limpio , 256 bytes

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]

Pruébalo en línea!

Elige:

  • un azar x(posición del personaje en el segmento)
  • un azar yque no es igual ax (posición del dígito en el segmento)
  • una letra minúscula aleatoria para cada posición que no sea igual xy no sea igual a ymenos que xsea ​​cero

1

JavaScript, 134 bytes

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)"))

Pruébalo en línea!

Esta respuesta eligió la cadena codificada de todas las posibles cadenas codificadas de manera uniforme. Por lo tanto, es más posible hacer que la letra codificada sea la primera.


1

C # (compilador interactivo de Visual C #) , 171 bytes

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));});}

Pruébalo en línea!

Explicación...

// 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)
      );
  });
}

1

Carbón , 35 30 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. 0 indexado. Explicación:

Nθ

Ingrese la longitud.

FS«

Ingrese la palabra y pase sobre los caracteres.

≔‽θη

Elija una posición aleatoria para la letra descifrada.

≔∧η‽Φθ⁻κηζ

Elija una posición aleatoria diferente para el dígito, a menos que la letra esté en la posición 0, en cuyo caso coloque también el dígito en la posición 0.

Fθ≡κ

Haga un bucle para cada carácter de salida y encienda la posición.

ζIη

Si esta es la posición del dígito, envíe la posición de la letra descifrada.

ηι

Pero si esta es la posición de la letra descifrada, entonces envíe la letra. Esto tiene prioridad sobre la posición del dígito porque el carbón vegetal toma la última entrada si varios casos de cambio tienen el mismo valor.

‽β

De lo contrario, genera una letra aleatoria.


0

05AB1E , 26 bytes

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

0 indexado.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

ε            # 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)
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.