Implemente este cifrado de clave

13

Implemente este cifrado de clave

Objetivo

Use el algoritmo (explicado en la sección Algoritmo) para implementar un determinado cifrado.

El programa debe leer la entrada de STDIN o el equivalente disponible más cercano, usar el algoritmo para generar el texto cifrado y una clave.

El texto cifrado y la clave se escribirán en STDOUT o el equivalente disponible más cercano. Se permite cualquier formato, siempre que emita el texto cifrado y la clave.

Algoritmo

Convierta los caracteres de la cadena en los valores ASCII respectivos. Por ejemplo:

Hello -> 72 101 108 108 111

A continuación, deberá generar una clave siempre que la cadena con números aleatorios en el rango de 0-9.

Hello -> 62841

Agregue los enteros en la secuencia de números aleatorios a los valores ASCII de la cadena. En los ejemplos anteriores, 72 se convertiría en 78 y 101 se convertiría en 104.

72 + 6 = 78, 101 + 2 = 103, 108 + 8 = 116, etc

A continuación, convierta los nuevos valores a caracteres. En los ejemplos anteriores, el texto se Helloha convertido Ngtpp.

Ejemplos

(Estos son simplemente ejemplos de cómo se vería la salida . La salida puede variar y variará).

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Reglas

  • Puede suponer que la entrada solo contendrá caracteres en el rango az, AZ y espacios.
  • Los envíos deben ser programas o funciones completos.
  • Las presentaciones se puntuarán en bytes.
  • Las lagunas estándar están prohibidas.
  • Este es el código de golf, por lo que gana el código más corto.

(Este es uno de mis primeros desafíos, si hay algo mal con él, no dude en decirme cómo podría mejorarlo).

m654
fuente
55
Este desafío me parece bien, excepto por un par de pensamientos. 1. ¿Se permite una función en lugar de un programa completo? Una pregunta relacionada es ¿podrían devolverse los valores en lugar de imprimirse? 2. Dijiste que preferably with the format (ciphertext)\n(key)."características preferidas" y el código de golf no se mezclan muy bien. Debe hacer que sea obligatorio o permitir otros formatos de salida. 3. ¿La clave debe imprimirse sin espacios? ¿Qué pasa con imprimirlo en formato de lista, por ejemplo [0, 5, 2, ...]?
James
¿Puede la clave tener ceros a la izquierda?
TheBikingViking
1
Buen primer desafío, pero no estoy tan seguro de los estrictos formatos de E / S. Por lo general, las funciones están permitidas y, por lo general, las respuestas pueden leerse desde uno de los métodos IO aceptados. Esto incluye la salida de una matriz con los elementos
Downgoat
1
¿Deben generarse los dígitos de la clave con una distribución uniforme?
Dennis
1
Uh ... 101 + 2 es 103, no 104. :-)
YetiCGN

Respuestas:

5

Jalea , 12 9 bytes

⁵ṁX€’Ṅ+OỌ

Pruébalo en línea!

Cómo funciona

⁵ṁX€’Ṅ+OỌ  Main link. Argument: s (string)

⁵             Set the return value to 10.
 ṁ            Mold; create an array of 10's with the length of s.
  X€          Pseudo-randomly pick a integer between 1 and 10, for each 10.
    ’         Decrement, so the integers fall in the range [0, ..., 9].
     Ṅ        Print the key, as an array, followed by a linefeed.
      +O      Add the integers to the ordinals (code points) of s.
        Ọ     Unordinal; convert back to characters.
Dennis
fuente
5

Python 3, 130 bytes

Gracias a @Rod por señalar un error

from random import*
def f(x):l=10**len(x);k=str(randint(0,l-1)+l)[1:];print(''.join(chr(ord(i)+int(j))for i,j in zip(x,k))+'\n'+k)

Una función que toma la entrada a través del argumento como una cadena e imprime en STDOUT.

Cómo funciona

from random import*  Import everything from the random module
def f(x):            Function with input string x
l=10**len(x)         Define l for later use as 10^length(x)
randint(0,l-1)+l     Generate a random integer in the range [0, l-1] and add l, giving a
                     number with l+1 digits...
k=str(...)[1:]       ...convert to a string and remove the first character, giving a key of
                     length l that can include leading zeroes, and store in k
for i,j in zip(x,k)  For each character pair i,j in x and k:
chr(ord(i)+int(j))    Find the UTF-8 code-point (same as ASCII for the ASCII characters),
                      add the relevant key digit and convert back to character
''.join(...)         Concatenate the characters of the ciphertext
print(...+'\n'+k)    Add newline and key, then print to STDOUT

Pruébalo en Ideone

TheBikingViking
fuente
su generador de claves no genera claves que comienzan con 0. aumentar los límites en un factor de 10 y eliminar el primer dígito debería solucionar: m=10**len(x);k=str(randint(m,m*10))[1:];e incluso guarda un byte en el proceso c:
Rod
@ Rod Gracias por señalar el error. Sin embargo, eso no guardará ningún byte, ya que randintes inclusivo, lo que significa que debería hacerlo m*10-1. Acabo de pensar en una forma de arreglarlo para el mismo recuento de bytes.
TheBikingViking
3

Pyth - 16 bytes

Esperando la decisión de OP sobre los formatos de salida.

sCM+VCMQKmOTQjkK

Test Suite .

Maltysen
fuente
Me decidí por el formato.
m654
3

En realidad, 17 bytes

;`X9J`M;(O¥♂cΣ@εj

Pruébalo en línea!

Explicación:

;`X9J`M;(O¥♂cΣ@εj
;                  dupe input
 `X9J`M            for each character in input copy:
  X9J                discard the character, push a random integer in [0, 9]
       ;           duplicate the offset array
        (O         bring input to top of stack, ordinal array
          ¥♂c      pairwise addition with offset array, turn each ordinal into a character
             Σ     concatenate
              @εj  concatenate the copy of the offset array
Mego
fuente
2

CJam - 14 bytes

Cuando vi el código ascii matemático, supe que tenía que escribir una respuesta CJam.

q_{;Amr}%_@.+p

Pruébelo en línea aquí .

Maltysen
fuente
2

MATL, 13 bytes

"10r*]v!kGy+c

El resultado se ve así:

9 5 8 2 1
Qjtnp

Pruébalo en línea!

Explicación:

"    ]          % For each character:
 10             % Push a 10 onto the stack
   r            % Push a random float in [O, 1)
    *           % Multiply. This essentially the same thing as pushing a number in [0, 10)
      v!k       % Join all of these together, and take the floor
         G      % Push the input again
          y     % Duplicate the array of random numbers
           +    % And add these together. Since MATL treats strings as an array of chars, we don't need to explicitly convert types
            c   % Display as string
James
fuente
No estoy seguro de si ese es el formato correcto ...
Leaky Nun
@Leaky Nun Cambié un poco las reglas.
m654
@ m654 ¿Dónde dijo que puede haber espacios entre los valores?
Leaky Nun
@LeakyNun Originalmente había una regla contra ellos, pero la eliminé.
m654
1
Buena idea usar el bucle. En realidad es más corto que la versión de entrada múltiple de roYr
Luis Mendo
2

PowerShell v2 +, 79 77 bytes

param($n)-join(($x=[char[]]$n|%{0..9|Random})|%{[char]($_+$n[$i++])});-join$x

Toma datos $n, recorre cada personaje y obtiene un Randomelemento de 0..9cada iteración. Almacena esos números (como una matriz) en $x. Tubos que se agrupan en otro bucle. Cada iteración, toma el elemento actual $_, lo agrega al carácter posicional cortado de $n(conversión implícita char-to-int), luego se vuelve a emitir como [char]. Deja eso en la tubería. Eso está encapsulado en parens y-join editado juntos para formar la palabra. Eso queda en la tubería. Además, el número $xtambién se -joinedita y se deja en la tubería. Estos se imprimen implícitamente con un Write-Outputal final de la ejecución, lo que hace que se impriman con una nueva línea de forma predeterminada.

Ejemplo

PS C:\Tools\Scripts\golfing> .\implement-this-key-cipher.ps1 'Hello World!'
Lhoot(Yt{mf"
433358259121
AdmBorkBork
fuente
2

C #, 252 247 245 232 216 Bytes

El tamaño es bastante malo en comparación con las otras soluciones, pero sin embargo ...

using System;using System.Linq;class p{static void Main(){var c="";var i=Console.ReadLine();var r=new Random();for(int b=0;b++<i.Count();){int d=r.Next(10);Console.Write((char)(i[b]+d));c+=d;}Console.Write("\n"+c);}}

Esta es mi segunda respuesta a un codegolf y soy bastante principiante considerando C #, así que agradecería saber cómo acortarlo :)

Sin golf:

using System;
using System.Linq;

class p
{
    static void Main()
    {
        var c = "";
        var i = Console.ReadLine();
        var r = new Random();
        for (int b = 0; b++ < i.Count();)
        {
            int d = r.Next(10);
            Console.Write((char)(i[b] + d));
            c += d;
        }
        Console.Write("\n" + c);
    }
}
  • Guardado 5 Bytes gracias a @FryAmTheEggman
  • Guardado 2 Bytes gracias a @theLambGoat
  • Guardado 7 Bytes al eliminar staticde la clase p
  • Guardado 24 Bytes gracias a @milk
Tom Doodler
fuente
1
El truco no es compararlo con otros lenguajes;) No estoy particularmente bien versado en C # golf, pero ¿puedes hacer b++<i.Count()y dejar vacía la tercera cláusula? Además, no creo que necesite una nueva línea final, por lo que la última llamada a WriteLinepodría ser Writeen su lugar.
FryAmTheEggman
Tampoco estoy bien versado en C #, pero creo que puede mover el = r.Next (10) hasta la declaración de d y guardar en un conjunto de paréntesis en la escritura. ¿O el azar no devuelve un int para que no puedas hacer eso?
theLambGoat
Creo que puedo hacer eso, déjame comprobarlo
Tom Doodler
Puede reemplazar los tipos con var. es decir, en var c=lugar de string c=afeitarse unos pocos bytes.
leche
¿Por qué no dejar el resultado de Console.ReadLine()como cadena? i.Lengthes más corto que i.Count(), no necesitará System.Linq. La cadena tiene un indexador de caracteres. También la creación de nuevos objetos al azar en el bucle es menos bytes: new Random().Next(10).
leche
2

CJam, 11 bytes

Nq{Amr_o+}/

Pruébalo en línea!

Cómo funciona

N            Push a linefeed on the stack.
 q           Read all input from STDIN and push it on the stack.
  {      }/  For each character in the input:
   Amr       Pseudo-randomly pick an integer in [0 ... 9].
      _o     Print a copy.
        +    Add the integer to the character.
             (implicit) Print the linefeed, followed by the modified characters.
Dennis
fuente
2

05AB1E , 18 17 bytes

vžh.RDyÇ+ç`?}J¶?,

Explicación

v           }      # for each char in input
 žh.RD             # push 2 copies of a random number in [0..9]
      yÇ+          # add 1 copy to the current chars ascii value
         ç`?       # convert to char, flatten and print
             J     # join stack (which contain the digits of the key)
              ¶?,  # print a newline followed by the key

Pruébalo en línea

Emigna
fuente
2

Python 3, 112 bytes

c es una función que devuelve el texto cifrado y la clave

from random import*
c=lambda t:map(''.join,zip(*[(chr(a+b),str(b))for a,b in((ord(i),randint(0,9))for i in t)]))

Aquí hay un código que hace lo mismo y es un poco más legible

def encrypt(text):
    # keep the codes of the letters in the input and a random key
    # that will be used later to encrypt this letter
    letter_and_key = ((ord(letter),randint(0,9)) for letter in text)

    # encrypt the letter and keep the key used as a string
    output_and_key = [(chr(letter_code+key), str(key))
                      for letter_code, key in letter_and_key]

    # At this point the values are kept in the format:
    # [(firstletter, firstkey), (secondletter, secondkey), ...]

    # to reorder the list to be able to output in the format "text key"
    text, key = map(''.join, zip(*output_and_key))

    # same as print(*output_and_key)
    return text, key

Salida:

>>> text, key = c('Hello World')
>>> print(text, key, sep='\n')
Liuot#`oylk
44935390707
Odrling
fuente
Bienvenido a este sitio!
James
1

PHP, 63 86 82 bytes

Editar: olvidé imprimir la clave ...

Gracias a Alex Howansky por salvarme 4 bytes.

for(;$i<strlen($a=$argv[1]);$s.=$r)echo chr(ord($a[$i++])+$r=rand(0,9));echo"
$s";

La entrada se da a través de un argumento de línea de comando. Toma cada carácter en la cadena y agrega un int aleatorio de 0-9 a su código ASCII, luego convierte el código nuevamente a ASCII. Se agrega cada número aleatorio $s, que se imprime al final.

Gato de negocios
fuente
También necesita imprimir la clave.
Alex Howansky
Puede colocar el $s.=$rdespués de la segunda semi en el bucle for, guardando un byte porque puede volcar su semi final. Entonces su bucle solo será una declaración para que pueda cortar las llaves de envoltura, ahorrando 2 bytes más. Luego, al final, puede poner el $sinterior de la cadena entre comillas, ahorrando al .operador un byte más. :)
Alex Howansky
@AlexHowansky: Eso es muy cierto. Gracias
Business Cat
1

J, 32 bytes

<@:e,:~[:<[:u:3&u:+e=.[:?[:$&10#

Python equivalente:

from random import randint
def encrypt(message):
    rand_list = list(map(lambda x: randint(0, 9), range(len(message))))
    return (''.join(list(map(lambda x,y: chr(x+y), rand_list, map(ord, message)))), rand_list)
ljeabmreosn
fuente
1

Perl, 34 bytes

Incluye +1 para -p

#!/usr/bin/perl -p
s%.%$\.=$==rand 10;chr$=+ord$&%eg
Ton Hospel
fuente
0

Perl, 65 bytes

for(split'',$ARGV[0]){$;.=$a=int rand 9;$b.=chr$a+ord}say"$b\n$;"

Me llevó un tiempo descubrir cómo obtener la entrada sin una nueva línea al final. Lo toma como una línea de comando arg

theLambGoat
fuente
Tu solución tiene algunos problemas. La entrada no se lee desde STDIN, $;no comienza vacía, por lo que imprime el contenido anterior y el rand nunca puede generar 9. Son fáciles de corregir y el uso de STDIN
acortará
@TonHospel Por lo general, los requisitos de entrada son sueltos y los argumentos son aceptables sobre STDIN y, si bien la entrada de STDIN es más corta, tener que quitar la nueva línea hace que sea más larga. Y aunque rand genera números <9, el método int de Perl redondea en lugar de pisos, por lo que cualquier cosa> = 8.5 debería terminar como 9
theLambGoat
Los requisitos de entrada generalmente están sueltos, pero aquí no. Conseguir nueva línea de STDIN no es fácil: <>=~/./g. Y no, inten perl se trunca hacia 0, no se redondea. perl -wle 'print int 8.6'salidas8
Ton Hospel
0

Python 2, 84 99 bytes

def f(x):y=`id(x)**len(x)`[1:len(x)+1];return''.join(map(chr,[ord(a)+int(b)for a,b in zip(x,y)])),y

Utiliza el id()valor de la cadena para generar números aleatorios.

Intentalo

atlasólogo
fuente
Tiene que generar la clave y el texto cifrado.
TheBikingViking
@TheBikingViking no sé cómo me perdí eso. Gracias - arreglado
atlasólogo
Creo que esto también tiene el mismo problema que una versión anterior de mi respuesta de Python; nunca produce claves con ceros a la izquierda.
TheBikingViking
@TheBikingViking Corregido nuevamente
atlasólogo
cambiar map(chr,[ord(a)+int(b)for a,b in zip(x,y)])a map(lambda x,y:chr(ord(x)+int(y)),x,y)? que debe salvar algo
ljeabmreosn
0

Senva , 74 bytes

Aquí está el programa más corto que he hecho:

2'(`>0.>{@}0'{v}2-2'0,{@}1'{v}0'{+}{'}9%+{^}{1-}1'"{+}{~}>$10.~0'2+"0,-:>$

¿Una pequeña explicación? (Nota: BM significa memoria de respaldo ):

// === Input and informations storing ===

2'  // Go to the 3rd cell (the two first will be used to store informations)
(   // Ask the user for a string (it will be stored as a suite of ASCII codes)
`   // Go the end of the string
>   // Make a new cell
0.  // Put a 0 to mark the end of the string
>   // Make a new cell, here will be stored the first random number
{@} // Store its adress in BM
0'  // Go to the 1st cell
{v} // Paste the adress, now the 1st cell contains the adress of the first random number
2-  // Subtract 2 because the string starts at adress 2 (the 3rd cell)
2'  // Go to the 3rd cell (where the string begins)

// === String encryption and displaying ===

0,  // While the current cell doesn't contain 0 (while we didn't reach the string's end)
  {@}  // Store the character's adress into the memory
  1'   // Go to the 2nd cell
  {v}  // Paste the value, now the 1st cell contains the adress of the current char
  0'   // Go to the 1st cell
  {+}  // Add the adress of the first random number to the current char adress
  {'}  // Go to this adrses
  9%+  // A random number between 0 and 10
  {^}  // Store this number in BM
  {1-} // Decrease BM (random number between 0 and 9)
  1'   // Go to the 1st cell
  "    // Go to the adress pointed by the cell (the adress of the current char)
  {+}  // Add it to the random number value
  {~}  // Display it as an ASCII character
  >    // Go to the next cell (the next character)
$   // End of the loop
10. // Set the new line's ASCII code into the current cell (which is now useless, so it can be overwritten)
~   // Display the new line
0'  // Go to the first cell
2+  // Add 2 to the adress, because we are not in the string loop : we cancel the 2 substraction
"   // Go to the pointed adress (the first random number's one)

// === Display the random numbers ===

0,  // While we didn't reach the end of the random numbers suite
    // That was why I stored numbers between 1 and 10, the first equal to 0 will be the end of the suite
  - // Decrease it (number between 0 and 9)
  : // Display the current random number as an integer
  > // Go to the next cell (the next number)
$ // End of the loop

Eso parece más grande ahora, cierto: p? Tal vez sea posible optimizar este código, pero por el momento es el más corto que he encontrado.

ClementNerma
fuente
0

C #, 174 bytes

using static System.Console;class b{static void Main(){var c=new System.Random();var d="\n";foreach(var e in ReadLine()){var f=c.Next(10);Write((char)(e+f));d+=f;}Write(d);}}

Sin golf:

using static System.Console;

class b
{
    static void Main()
    {
        var c = new System.Random();
        var d = "\n";

        foreach (var e in ReadLine())
        {
            var f = c.Next(10);
            Write((char)(e + f));
            d += f;
        }

        Write(d);
    }
}

Bastante sencillo, de verdad.

Scepheo
fuente
0

Perl 6: 55 o 70 bytes

Como una función anónima que toma un parámetro de cadena y devuelve una lista de dos cadenas (54 caracteres, 55 bytes) :

{my @n=^9 .roll(.ords);(.ords Z+@n)».chr.join,@n.join}

Como un programa que lee desde STDIN y escribe en STDOUT (69 caracteres, 70 bytes) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
smls
fuente