Implemente essa cifra de chave

13

Implemente essa cifra de chave

Objetivo

Use o algoritmo (explicado na seção Algoritmo) para implementar uma determinada cifra.

O programa deve ler a entrada do STDIN ou o equivalente mais próximo disponível, usar o algoritmo para gerar o texto cifrado e uma chave.

O texto cifrado e a chave serão gravados em STDOUT ou no equivalente mais próximo disponível. Qualquer formato é permitido, desde que ele produza o texto cifrado e a chave.

Algoritmo

Converta os caracteres na sequência nos respectivos valores ASCII. Por exemplo:

Hello -> 72 101 108 108 111

Em seguida, você precisará gerar uma chave desde que a sequência com números aleatórios no intervalo de 0 a 9.

Hello -> 62841

Adicione os números inteiros na sequência de números aleatórios aos valores ASCII da sequência. Nos exemplos acima, 72 se tornaria 78 e 101 se tornaria 104.

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

Em seguida, converta os novos valores novamente em caracteres. Nos exemplos acima, o texto Hellose tornou Ngtpp.

Exemplos

(Estes são apenas exemplos de como a saída pode ser. A saída pode e irá variar.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Regras

  • Você pode assumir que a entrada conterá apenas caracteres no intervalo az, AZ e espaços.
  • As submissões devem ser programas ou funções completos.
  • As submissões serão pontuadas em bytes.
  • As brechas padrão são proibidas.
  • Isso é código-golfe, então o código mais curto vence.

(Esse é um dos meus primeiros desafios, se houver algo errado com isso, fique à vontade para me dizer como eu poderia melhorá-lo.)

m654
fonte
5
Esse desafio parece bom para mim, exceto por alguns pensamentos. 1. É permitida uma função em vez de um programa completo? Uma pergunta relacionada é: os valores poderiam ser retornados em vez de impressos? 2. Você disse que preferably with the format (ciphertext)\n(key)."recursos preferenciais" e código de golfe não se misturam muito bem. Você deve tornar isso obrigatório ou permitir outros formatos de saída. 3. A chave precisa ser impressa sem espaços? Que tal imprimi-lo em formato de lista, por exemplo [0, 5, 2, ...]?
James
A chave pode ter zeros à esquerda?
TheBikingViking
1
Bom primeiro desafio, mas não tenho tanta certeza dos formatos rígidos de IO. Geralmente, as funções são permitidas e, geralmente, as respostas podem ser lidas em um dos métodos de IO aceitos. Isto inclui a saída de um array com os itens
Downgoat
1
Os dígitos da chave precisam ser gerados com uma distribuição uniforme?
Dennis
1
Uh ... 101 + 2 é 103, não 104. :-)
YetiCGN

Respostas:

5

Geléia , 12 9 bytes

⁵ṁX€’Ṅ+OỌ

Experimente online!

Como 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
fonte
5

Python 3, 130 bytes

Obrigado a @Rod por apontar um bug

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)

Uma função que recebe entrada via argumento como uma sequência e imprime em STDOUT.

Como 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

Experimente no Ideone

TheBikingViking
fonte
seu gerador de chaves não gera chaves começando com 0. aumentar os limites em um fator de 10 e remover o primeiro dígito deve ser corrigido: m=10**len(x);k=str(randint(m,m*10))[1:];e você ainda salva um byte no processo c:
Rod
@ Rod Obrigado por apontar o bug. Isso não salvará bytes, no entanto, já que randinté inclusivo, o que significa que você precisaria fazer m*10-1. Eu apenas pensei em uma maneira de corrigi-lo para a mesma contagem de bytes.
TheBikingViking
3

Pitão - 16 bytes

Aguardando decisão do OP nos formatos de saída.

sCM+VCMQKmOTQjkK

Conjunto de Teste .

Maltysen
fonte
Eu decidi sobre o formato.
M654
3

Na verdade, 17 bytes

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

Experimente online!

Explicação:

;`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
fonte
2

CJam - 14 bytes

Quando vi a matemática do código ascii, sabia que tinha que escrever uma resposta CJam.

q_{;Amr}%_@.+p

Experimente online aqui .

Maltysen
fonte
2

MATL, 13 bytes

"10r*]v!kGy+c

A saída é assim:

9 5 8 2 1
Qjtnp

Experimente online!

Explicação:

"    ]          % 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
fonte
Eu não tenho certeza se esse é o formato certo ...
Leaky Nun
Freira @Leaky eu mudei as regras um pouco.
M654
@ m654 Onde você disse que pode haver espaços entre os valores?
Leaky Nun
@LeakyNun Originalmente, havia uma regra contra eles, mas eu a removi.
M654
1
Boa idéia para usar o loop. Na verdade, é mais curto que a versão de entrada múltipla de rouYr
Luis Mendo
2

PowerShell v2 +, 79 77 bytes

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

Recebe entrada $n, faz um loop sobre cada caractere e obtém um Randomelemento de 0..9cada iteração. Armazena esses números (como uma matriz) em $x. Tubos que se agrupam em outro loop. Cada iteração, pega o elemento atual $_, o adiciona ao caracter posicional cortado em $n(conversão implícita de char para int) e, em seguida, é re-convertido como [char]. Deixa isso no pipeline. Isso é encapsulado em parênteses e edificado -joinpara formar a palavra. Isso fica na calha. Além disso, o número $xtambém é -joineditado e deixado no pipeline. Esses são implicitamente impressos com umWrite-Output no final da execução, o que resulta em serem impressos com uma nova linha por padrão.

Exemplo

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

C #, 252 247 245 232 216 bytes

O tamanho é muito ruim em comparação com as outras soluções, mas mesmo assim ...

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 é minha segunda resposta a um codegolf e eu sou bastante iniciante, considerando C #, então eu gostaria de saber como diminuí-lo :)

Ungolfed:

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 graças a @FryAmTheEggman
  • Guardado 2 Bytes graças a @theLambGoat
  • Economizou 7 bytes removendo static da classe p
  • Guardado 24 bytes graças a @milk
Tom Doodler
fonte
1
O truque é não comparar com outros idiomas;) Eu não sou particularmente versado em golfe em C #, mas você pode fazer b++<i.Count()e deixar a terceira cláusula vazia? Além disso, não acho que você precise de uma nova linha à direita; portanto, a última chamada para WriteLinepoderia ser Write.
FryAmTheEggman
Também não sou versado em c #, mas acho que você pode mover o = r. Next (10) até a declaração de d e salvar em um conjunto de parênteses na gravação. Ou o random não retorna um int para que você não possa fazer isso?
TheLambGoat
Eu acho que eu posso fazer isso, deixe-me ver
Tom Doodler
Você pode substituir tipos por var. ie- em var c=vez de string c=raspar alguns bytes.
milk
Por que não deixar o resultado de Console.ReadLine()como string? i.Lengthé menor que i.Count(), você não precisará do System.Linq. string possui um indexador de char. Também a criação de new Random objetos no circuito é menos bytes: new Random().Next(10).
milk
2

CJam, 11 bytes

Nq{Amr_o+}/

Experimente online!

Como 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
fonte
2

05AB1E , 18 17 bytes

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

Explicação

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

Experimente online

Emigna
fonte
2

Python 3, 112 bytes

c é uma função que retorna o texto criptografado e a chave

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

Aqui está um código que faz a mesma coisa e é um pouco mais legível

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

Resultado:

>>> text, key = c('Hello World')
>>> print(text, key, sep='\n')
Liuot#`oylk
44935390707
odrling
fonte
Bem-vindo a este site!
James
1

PHP, 63 86 82 bytes

Edit: esqueceu de imprimir a chave ...

Obrigado a Alex Howansky por me salvar 4 bytes.

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

A entrada é fornecida através de um argumento de linha de comando. Pega cada caractere na sequência e adiciona um int aleatório de 0 a 9 ao seu código ASCII, depois converte o código novamente em ASCII. Todo número aleatório é anexado a $s, que é impresso no final.

Gato de negócios
fonte
Você precisa imprimir a chave também.
precisa saber é o seguinte
Você pode colocar o $s.=$rdepois da 2ª semi no loop for, salvando um byte porque pode despejar sua semi final. Então, seu loop será apenas uma instrução, para que você possa cortar as chaves de empacotamento, economizando mais 2 bytes. Em seguida, no final, você pode colocar o $sinterior da cadeia de caracteres citada, salvando o .operador por mais um byte. :)
Alex Howansky
@AlexHowansky: Isso é verdade. Obrigado
Business Cat
1

J, 32 bytes

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

equivalente em python:

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
fonte
1

Perl, 34 bytes

Inclui +1 para -p

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

Perl, 65 bytes

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

Levei um tempo para descobrir como obter a entrada sem uma nova linha no final. Toma como uma linha de comando arg

theLambGoat
fonte
Sua solução tem alguns problemas. Entrada não é lido forma STDIN, $;não começar vazia para que ele imprime o conteúdo antigo eo rand nunca pode gerar 9. Eles são fáceis de corrigir e usando STDIN vai fazer seu código mais curto :-)
Ton Hospel
@TonHospel Normalmente, os requisitos de entrada são frouxos e os argumentos são aceitáveis ​​em relação ao STDIN e, embora a entrada de STDIN seja mais curta, ter que remover a nova linha dela torna-a mais longa. E enquanto rand gera números <9, do Perl método int rodadas em vez de pisos então qualquer coisa> = 8.5 deve acabar como 9
theLambGoat
Os requisitos de entrada geralmente são frouxos, mas aqui não era. Obtendo non nova linha de STDIN é fácil: <>=~/./g. E não, intem perl trunca para 0, ele não arredonda. perl -wle 'print int 8.6'saídas8
Ton Hospel 23/08/16
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

Usa o id()valor da sequência para gerar números aleatórios.

Tente

atlasologist
fonte
Você precisa produzir a chave e o texto cifrado.
TheBikingViking
@TheBikingViking não sabe como eu perdi isso. Obrigado - corrigido
atlasologist
Eu acho que isso também tem o mesmo problema que uma versão anterior da minha resposta Python; nunca produz chaves com zeros à esquerda.
TheBikingViking
@TheBikingViking Corrigido novamente
atlasologist
mudar map(chr,[ord(a)+int(b)for a,b in zip(x,y)])para map(lambda x,y:chr(ord(x)+int(y)),x,y)? que deve salvar alguma coisa
ljeabmreosn
0

Senva , 74 bytes

Aqui está o programa mais curto que eu fiz:

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

Uma pequena explicação? (Nota: BM significa Back-Memory ):

// === 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

Isso parece maior agora, é verdade: p? Talvez seja possível otimizar esse código, mas, no momento, é o mais curto que encontrei.

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

Ungolfed:

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

Bem simples, realmente.

Scepheo
fonte
0

Perl 6: 55 ou 70 bytes

Como uma função anônima que aceita um parâmetro de string e retorna uma lista de duas strings (54 caracteres, 55 bytes) :

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

Como um programa que lê STDIN e grava em STDOUT (69 caracteres, 70 bytes) :

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