Cifra de Computador

14

Introdução:

Tenho muitas cifras diferentes armazenadas em um documento que compilei quando criança, escolhi algumas das que achei mais adequadas para desafios (não muito triviais e nem muito difíceis) e as transformei em desafios. A maioria deles ainda está na caixa de areia, e ainda não tenho certeza se vou postar todos, ou apenas alguns. Mas aqui está o primeiro deles a começar.


Uma Cifra de Computador codificará o texto fornecido em grupos de caracteres 'aleatórios' de uma determinada informação length. Se esse grupo contiver um dígito, ele será usado para indexar em seu próprio grupo o caractere codificado. Se nenhum dígito estiver presente no grupo, significa que o primeiro caractere é usado.

Por exemplo, digamos que queremos codificar o texto this is a computer ciphercom um determinado comprimento de 5. Esta é uma saída potencial (nota: os números são indexados 1 no exemplo abaixo):

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)

Vamos dar alguns grupos como exemplos para explicar como decifrar o grupo:

  • qu5dt: Este grupo contém um dígito 5, assim que o (1-indexada) 5 caráter deste grupo é o caráter usado para o texto decifrado: t.
  • hprit: Este grupo não contém dígitos, de modo que o primeiro caractere desse grupo é usado implicitamente para o texto decifrado: h.
  • osyw2: Este grupo contém um dígito 2, assim que o (1-indexada) 2º caráter deste grupo é o caráter usado para o texto decifrado: s.

Desafio:

Dado um número inteiro lengthe uma sequência word_to_encipher, produza uma sequência codificada aleatória, conforme descrito acima.

Você só precisa codificar os dados lengthe word_to_encipher, portanto, não é necessário criar um programa / função de decifração também. No entanto, posso fazer um desafio da parte 2 para a decifração no futuro.

Regras do desafio:

  • Você pode assumir que o valor lengthestará no intervalo [3,9].
  • Você pode assumir word_to_encipherque conterá apenas letras.
  • Você pode usar letras minúsculas ou maiúsculas completas (indique qual delas você usou na sua resposta).
  • Suas saídas, cada grupo e as posições dos dígitos em um grupo (se houver) devem ser uniformemente aleatórias . Portanto, todas as letras aleatórias do alfabeto têm a mesma chance de ocorrer; a posição da letra criptografada em cada grupo tem a mesma chance de ocorrer; e a posição do dígito tem a mesma chance de ocorrer (exceto quando é o primeiro caractere e nenhum dígito está presente; e obviamente não pode estar na mesma posição que o caractere codificado).
  • Você também pode usar dígitos indexados a 0 em vez de indexados a 1. Indique qual dos dois você usou na sua resposta.
  • O dígito 1(ou 0quando indexado com 0) nunca estará presente na saída. Portanto, b1ndhnão é um grupo válido para codificar o caractere 'b'. No entanto, b4tbwé válido, onde os 4encripta os bna posição 4 (1-indexada), e os outros caracteres b, t, wsão aleatórios (que por coincidência, também contém um b). Outros grupos válidos possíveis de length5 para codificar o caractere 'b' são: abcd2, ab2de, babbk, hue5b, etc.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

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
fonte
2
Como "uniforme" significa
l4m2
@ l4m2 Que existe uma chance igual para qualquer saída. Portanto, todas as letras aleatórias do alfabeto têm a mesma chance de ocorrer; a posição da letra criptografada em cada grupo tem a mesma chance de ocorrer; e a posição do dígito tem a mesma chance de ocorrer (exceto quando é o primeiro caractere e nenhum dígito está presente, e também não está na mesma posição que o caractere codificado).
Kevin Cruijssen
Assim abcd2, ab2de, babbktudo mesmo? Também é b1akkválido?
L4m2
@ l4m2 Sim, todas as três são saídas possíveis que codificam o caractere 'b'. Quanto a b1akkeu diria que não. Irá editá-lo na descrição do desafio para esclarecer. Se o primeiro caractere for o codificado, nenhum dígito deve estar presente.
Kevin Cruijssen
1
Por exemplo, quando length = 3, char = "a"; O formulário "a??"tem 676 possíveis resultados, mas "1a?", "?a1", "2?a", "?2a", tem only104 resultados. Portanto, se estou tentando escolher um resultado de todos esses resultados do 780, a distribuição da "posição da letra criptografada" é 13: 1: 1, não 1: 1: 1. E eu consideraria isso como o trabalho "uniformemente aleatório".
tsh

Respostas:

3

Pitão, 22 bytes

smsXWJOQXmOGQJdO-UQJJz

Experimente online.

Usa letras minúsculas e indexação zero.

Explicação

Algoritmo muito simples.

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

Experimente online!

Leva entrada e saída em maiúsculas. Leva a entrada ao curry, como f(n)(string). Usa 1 indexação.

Explicação:

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

Experimente online!

Usa letras maiúsculas e números indexados em 0.

-3 bytes, graças a Kevin Cruijssen

TFeld
fonte
@KevinCruijssen Thanks :)
TFeld
O que sample(R(l),2)[::1|-(random()<.5)]significa isso ?
L4m2
@ l4m2 Retira 2 números range(l)e os embaralha. Mas, aparentemente amostra não garantir a ordem, por isso não é necessário :)
TFeld
Você não pode remover os parênteses (j==i)*(n>0)? A multiplicação tem precedência de operador sobre a subtração, não é?
Kevin Cruijssen
1
@KevinCruijssen Sim, eu esqueci de removê-los, quando tive alguns problemas #
TFeld
3

JavaScript (Node.js) , 135 bytes

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

Experimente online!

Obrigado Arnauld por 1B

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

Experimente online!

Leva letras maiúsculas.

Explicação do código antigo (principalmente a mesma abordagem):

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

Experimente online!

  • O índice é baseado em 0.
  • Esta entrada usa um IntStream(obtido String::chars) como entrada, bem como um número e retorna outro IntStream.
  • As transmissões de doublepara intsão desnecessárias devido ao +=hack.
Olivier Grégoire
fonte
2

Japonês , 29 bytes

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

Experimente online!

Indexado a zero.

Explicação:

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

Experimente online!

Indexado a 0, minúsculo.

Um pouco sem golfe e 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);
}

O código deve ser bem direto. Os dois randoms i,j gerados em uma rand()chamada, são bons como independentes, pois gcd ( n, ~-n) = 1 e RAND_MAXé grande.

attinat
fonte
1
Bem-vindo ao PPCG! :)
Salsicha
1

Limpo , 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]

Experimente online!

Escolhe:

  • aleatório x (posição do personagem no segmento)
  • aleatório y que não é igual a x(posição do dígito no segmento)
  • uma letra minúscula aleatória para cada posição diferente xe igual a y, a menos que xseja zero
Furioso
fonte
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)"))

Experimente online!

Esta resposta escolheu a sequência codificada de todas as sequências codificadas possíveis de maneira uniforme. Portanto, é mais possível criar a letra codificada como a primeira.

tsh
fonte
1

C # (compilador interativo do 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));});}

Experimente online!

Explicação...

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

Carvão , 35 30 bytes

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

Experimente online! Link é a versão detalhada do código. Indexado a 0. Explicação:

Nθ

Insira o comprimento.

FS«

Insira a palavra e faça um loop sobre os caracteres.

≔‽θη

Escolha uma posição aleatória para a letra decifrada.

≔∧η‽Φθ⁻κηζ

Escolha uma posição aleatória diferente para o dígito, a menos que a letra esteja na posição 0; nesse caso, coloque o dígito também na posição 0.

Fθ≡κ

Faça um loop uma vez para cada caractere de saída e ative a posição.

ζIη

Se esta for a posição do dígito, emita a posição da letra decifrada.

ηι

Mas se essa é a posição da letra decifrada, emita a letra. Isso tem precedência sobre a posição do dígito porque o carvão vegetal faz a última entrada se vários casos de chave tiverem o mesmo valor.

‽β

Caso contrário, imprima uma letra aleatória.

Neil
fonte
0

05AB1E , 26 bytes

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

Indexado a 0.

Experimente online ou verifique todos os casos de teste .

Explicação:

ε            # 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
fonte