fundo
Um bloco de uso único é uma forma de criptografia que se provou impossível de decifrar se usada corretamente.
A criptografia é realizada usando um texto sem formatação (composto apenas de letras AZ) e gerando uma sequência aleatória no mesmo comprimento (também apenas letras). Essa string atua como a chave. Cada caractere no texto simples é então emparelhado com o caractere correspondente na chave. O texto cifrado é calculado da seguinte forma: Para cada par, os dois caracteres são convertidos em números (A = 0, B = 1, ... Z = 25). Os dois números são adicionados ao módulo 26. Esse número é convertido novamente em um caractere.
Descriptografia é exatamente o oposto. Os caracteres no texto cifrado e na chave são emparelhados e convertidos em números. A chave é então subtraída do módulo de texto cifrado 26 e o resultado é convertido novamente em um caractere AZ.
O desafio
Seu desafio é escrever o programa mais curto possível que possa criptografar e descriptografar um bloco único.
Na primeira linha de entrada (para STDIN), haverá a palavra "ENCRYPT" ou a palavra "DECRYPT".
Se a palavra estiver criptografada, a próxima linha será o texto sem formatação. Seu programa deve gerar duas linhas (para STDOUT), sendo a primeira a chave e a segunda o texto cifrado.
Se a palavra for descriptografada, seu programa receberá mais duas linhas de entrada. A primeira linha será a chave e a segunda linha será o texto cifrado. O programa deve gerar uma linha, que será o texto sem formatação que foi descriptografado.
O texto sem formatação, o texto cifrado e a chave devem sempre consistir em letras maiúsculas AZ. Eles sempre serão uma única linha e não conterão espaços em branco.
A chave deve sempre ser aleatória. Nenhuma parte grande dela deve se repetir entre as execuções e não deve haver padrões que possam ser encontrados no texto.
Dois exemplos simples:
ENCRYPT
HAPPYBIRTHDAY
>ABKJAQLRJESMG
>HBZYYRTICLVME
DECRYPT
ABKJAQLRJESMG
HBZYYRTICLVME
>HAPPYBIRTHDAY
O >
representa quais linhas são enviadas, assim você não precisa imprimir esse símbolo como saída.
fonte
/dev/random
,haveged
), criptografe xorando as ordens com os bytes e descriptografando-as com a chave. gist.github.com/5078264 a chave ou a aleatoriedade pode ser lida em stdin, a mensagem ou o cyphertext pode ser um argumento de nome de arquivo./dev/hwrng
, em vez de usar pseudo aleatório (que tecnicamente o torna quebrado).Respostas:
GolfScript, 53 caracteres
Essa é uma tarefa para a qual o GolfScript parece perfeitamente adequado.
Para manter o código curto, estou usando o mesmo código para criptografia e descriptografia: para descriptografar, subtraio a chave do texto cifrado, enquanto que para criptografia, primeiro gere um texto cifrado aleatório e depois subtraio o texto sem formatação. Mesmo assim, o código extra para implementar o modo de criptografia ocupa pouco mais da metade do tamanho do programa.
Versão descolada com comentários:
fonte
Ruby (
200185)execuções de amostra + wc:
fonte
s[k=(p=f).map{rand 26}],r[k,p,:-]
deve ser escritos[k=f.map{rand 26}],r[k,$_,:-]
$_
é apenas a última linha lida porgets
.f
também faz.scan(/./).map{|b|b.ord-65}
depois de ler uma linha.Haskell, 203 caracteres
Exemplo:
fonte
Perl,
220171 caracteresExemplo de execução:
Nota: pelo menos quando o executo, "Pressione qualquer tecla para continuar ..." é anexado ao final da última saída. Espero que esteja tudo bem, porque não faz parte do programa. Caso contrário, posso fazê-lo aparecer na próxima linha.
Este é o meu primeiro programa real em Perl e o meu primeiro golfe, então eu realmente aprecio dicas. Também encontrei
/(.)/g
na internet, mas não faço ideia de como funciona (é uma expressão regular? Ainda não as aprendi). Alguém pode me explicar?EDIT: Obrigado a Ilmari Karonen por me ajudar com os regexps, usei meu novo conhecimento para salvar 7 caracteres!
Versão expandida e ligeiramente legível:
fonte
/(.)/g
é uma regexp. Você definitivamente vai querer aprender isso se quiser jogar golfe Perl. perldoc.perl.org/perlre.html não é um ponto de partida ruim.Python -
304295Acredito que isso atenda exatamente às especificações
(inclusiveEle não valida a entrada, então acho que produzirá apenas saída de lixo se você fornecer caracteres fora de'>'
no início dos prompts de entrada.)[A-Z]
. Ele também verifica apenas a primeira letra do comando de entrada. Qualquer coisa que comece comD
resultará em descriptografia e qualquer outra coisa resultará em criptografia.fonte
>
, estava apenas usando-o para demonstrar quais linhas foram produzidas. Você não precisa implementá-las.C ++ -
220241 caracteres, 4 linhasEditar 1 - A biblioteca padrão do MSVS parece incluir muitos arquivos desnecessários, o que significava que o ios tinha todas as inclusões necessárias, mas isso não funcionava com outros compiladores. Ios alterados para os arquivos reais em que as funções necessárias aparecem no cstdlib e no cstdio. Agradecemos a Ilmari Karonen por apontar isso.
fonte
g++ otp.cpp
dizotp.cpp: In function ‘int main()’: otp.cpp:3: error: ‘scanf’ was not declared in this scope otp.cpp:3: error: ‘rand’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope
Python - 270
Saída de amostra:
Contador de caracteres:
fonte
J: 94 bytes
Todo o espaço em branco necessário contava.
Versão comentada:
fonte
C # (
445416)Esqueceu o agregado. Corte um pouco.
Um pouco jogado:
}
Golfe:
fonte
C (159 + 11 para sinalizadores do compilador)
Golfe:
Ungolfed:
Compile com
-Dg=gets(s)
.Exemplo:
fonte
JavaScript 239
Uso:
fonte
Ruby -
184179177 caracteresExecute-o assim:
$ ruby pad-lock.rb
Aqui está a versão não destruída, se alguém estiver interessado (embora não esteja completamente atualizado com a versão golfada)
fonte