A cifra VIC é uma das mais complicadas cifras de lápis e papel já criadas. Utilizado na década de 1950 pelo espião soviético Reino Häyhänen, codinome "VICTOR", seu principal princípio é a segurança através da ofuscação; um monte de confusão.
Sua tarefa é escrever um programa ou função que receba uma mensagem e a codifique usando a cifra VIC. Também publiquei um desafio do decodificador de codificação VIC aqui . Se alguma das seguintes instruções não for clara, não hesite em perguntar sobre elas nos comentários. As instruções são adaptadas deste site .
Codificando a codificação VIC
Preparação
Você precisará de cinco entradas:
- a mensagem de texto sem formatação
- uma palavra-chave ou frase curta que contém as letras mais comuns no seu idioma
- uma frase-chave, como uma citação ou uma linha de uma música (pelo menos 20 caracteres)
- uma data (ou outro número com seis dígitos ou mais)
- um número de agente pessoal
Na prática, esses quatro últimos devem ser previamente acordados entre o remetente e o destinatário, incluindo se o número de agente do remetente ou do destinatário é usado na codificação.
Meu exemplo de mensagem será: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
Codificaremos em inglês (embora você possa usar o idioma e o alfabeto de sua preferência) e as letras mais comuns do alfabeto em inglês A, E, I, N, O, R, S, T
. Vou usar a palavra-chave SENATORI
.
Minha frase-chave é uma citação de Richard Feynman: "O primeiro princípio é que você não deve se enganar - e você é a pessoa mais fácil de se enganar".
Como data, usarei 31 de julho de 2016 (no formato 3172016
), que é o dia em que escrevi essa descrição.
O número pessoal que eu escolhi para mim é 9
.
Resumo das etapas
- Derive as chaves intermediárias para usar nas etapas a seguir.
- Construa e aplique o tabuleiro de damas abrangido.
- Construa e aplique a primeira tabela de transposição.
- Construa e aplique a segunda tabela de transposição (interrompida).
- Finalize a mensagem inserindo o grupo de indicadores de mensagens.
Submecanismos
Mais duas coisas a explicar antes de entrarmos na questão: os processos de adição e seqüencialização de cadeias.
A adição de cadeia, também conhecida como gerador de Fibonacci defasado, funciona tomando uma sequência de dígitos inicial, adicionando os dois primeiros dígitos sem carregar (adicione-os juntos mod 10
) e anexando o resultado ao final. Por exemplo:
79081
7 + 9 = 6
790816
9 + 0 = 9
7908169
0 + 8 = 8
79081698
8 + 1 = 9
790816989
1 + 6 = 7
7908169897
... and so on
Seqüencializar é essencialmente pegar uma sequência de letras ou dígitos e rotulá-los por ordem alfabética / numérica. As duplicatas são rotuladas da esquerda para a direita. Por exemplo:
E X A M P L E
0 # A
1 0 2 # Es
1 0 3 2 # L
1 0 4 3 2 # M
1 0 4 5 3 2 # P
1 6 0 4 5 3 2 # X
3 3 0 5 8 4 2 0 4 7 5 4 8 1
0 1 # 0s
0 1 2 # 1
0 3 1 2 # 2
4 5 0 3 1 2 # 3s
4 5 0 6 3 1 7 8 2 # 4s
4 5 0 9 6 3 1 7 10 8 2 # 5s
4 5 0 9 6 3 1 7 11 10 8 2 # 7
4 5 0 9 12 6 3 1 7 11 10 8 13 2 # 8s
Eu uso a indexação zero aqui, mas indexe como quiser.
1. Teclas intermediárias
Divida as primeiras 20 letras da frase-chave em dois grupos de 10 e sequencie cada uma individualmente, que chamaremos de S1
e S2
.
THEFIRSTPR
S1: 8201357946
INCIPLEIST
S2: 2603751489
Escolha um identificador de mensagem aleatório de 5 dígitos M
(pode ser uma das entradas, se você preferir):
M = 47921
Subtraia, sem emprestar (subtraia mod 10
), os cinco primeiros dígitos da data fixada 3172016
de M
:
M 47921
date - 31720
= 16201
Cadeia adicione o resultado até você ter dez dígitos:
1620178218
Adicione esses dígitos a S1
, sem carregar ou mod 10
, para obter G
:
1620178218
S1 + 8201357946
G = 9821425154
Acima S2
, escreva a sequência 0123456789. Localize cada dígito G
na sequência 0123456789 e substitua-o pelo dígito diretamente abaixo dele em S2
. O resultado é T
.
0123456789
S2 2603751489
G 9821425154
T 9806705657
Use a adição de cadeia para expandir T
para 60 dígitos.
9806705657
becomes
980670565778637511245490262369939288595822106344304316978734
Esses últimos 50 dígitos, em cinco linhas de dez dígitos cada, formam o U
bloco.
T 9806705657
U 7863751124
5490262369
9392885958
2210634430
4316978734
Os dois últimos dígitos não iguais do U
bloco são adicionados individualmente ao número pessoal do agente para fornecer as larguras das duas transposições, p
e q
.
9 + 3 = 12 (p, primeira largura de transposição) 9 + 4 = 13 (q, segunda largura de transposição)
Seqüencialize T
e use essa sequência para copiar as colunas do U
bloco, de cima para baixo, em uma nova linha de dígitos V
,.
T 9806705657
seqT 9804612537
U 7863751124
5490262369
9392885958
2210634430
4316978734
V 69911 56837 12548 26533 30206 13947 72869 49804 84323 75924
Seqüencialize os primeiros p
dígitos para obter a tecla para a primeira transposição K1
e os q
dígitos seguintes para a tecla para o segundo K2
.
First 12 6 9 9 1 1 5 6 8 3 7 1 2
K1 6 10 11 0 1 5 7 9 4 8 2 3
Next 13 5 4 8 2 6 5 3 3 3 0 2 0 6
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
Por fim, sequencialmente, a linha final do U
bloco a ser obtida C
, os cabeçalhos das colunas do tabuleiro de damas abrangido:
U5 4316978734
C 3105968724
2. Quadriculado
Primeiro, darei meu exemplo de tabuleiro de xadrez e depois explicarei os princípios para criá-lo dessa maneira:
3 1 0 5 9 6 8 7 2 4
S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #
A primeira linha de letras é a nossa palavra-chave curta SENATORI
. Sua palavra-chave pode ser qualquer sequência sem duplicatas, mas como define a linha superior do tabuleiro de damas, escolha sabiamente. Acima da palavra-chave está C
, e as outras linhas estão no restante do alfabeto, na ordem que você escolher. No meu caso, preenchi o tabuleiro de damas com o restante do alfabeto latino, um sinal de pontuação .
e um sinal de demarcação de números #
. Essencialmente, o tabuleiro de damas é uma cifra de substituição sofisticada. Por exemplo, "E" será substituído por 1
e "W" será substituído por 27
.
Depois de codificarmos nossa mensagem em texto sem formatação com esse tabuleiro de damas, mas primeiro, precisamos tornar o início de nossa mensagem menos óbvio dividindo-o em uma posição aleatória e deixando tudo em maiúsculas. Para indicar o outro começo original, usamos dois pontos completos..
We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
torna-se
HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT
Codificamos com o tabuleiro de damas, dando-nos:
407020 1293124 496481 96 354114062831 416479869443442424 271 581
2173436481812124 95451 274059 22628 435024 232880 14818229
Se o comprimento da mensagem não for divisível por 5, adicionamos alguns caracteres nulos para preencher a mensagem. Nossa mensagem tem 109 dígitos, então adicionarei um nulo: "4".
40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294
Nota: Como meu exemplo de mensagem não contém números, direi aqui que você pode designar, digamos, como #3#
, que é codificado como 44344
aqui.
3. Primeira transposição
Crie a tabela de transposição escrevendo K1
(na seção Chaves Intermediárias), seguido pela mensagem codificada da etapa anterior, em linhas do mesmo comprimento, abaixo da chave:
K1 6 10 11 0 1 5 7 9 4 8 2 3
4 0 7 0 2 0 1 2 9 3 1 2
4 4 9 6 4 8 1 9 6 3 5 4
1 1 4 0 6 2 8 3 1 4 1 6
4 7 9 8 6 9 4 4 3 4 4 2
4 2 4 2 7 1 5 8 1 2 1 7
3 4 3 6 4 8 1 8 1 2 1 2
4 9 5 4 5 1 2 7 4 0 5 9
2 2 6 2 8 4 3 5 0 2 4 2
3 2 8 8 0 1 4 8 1 8 2 2
9 4
Tomando as colunas numeradas na ordem de seus números, obtemos:
060826428 246674580 151411542 246272922 961311401 082918141
4414434239 118451234 334422028 293488758 0417249224 794943568
4. Segunda transposição
A primeira transposição foi relativamente simples. Este, no entanto, é uma transposição interrompida. O padrão de interrupção é determinado pela largura da tabela e da chave. No nosso exemplo, temos 110 dígitos e 13 colunas, o que significa que teremos 8 linhas completas e 6 sobras. Começamos a preencher a primeira linha, mas paramos na coluna 0 e continuamos da seguinte forma:
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 stop at 0
2 4 6 6 7 4 5 8 0 1 continue in a triangle pattern
5 1 4 1 1 5 4 2 2 4 6
2 7 2 9 2 2 9 6 1 3 1 1
4 0 1 0 8 2 9 1 8 1 4 1 4 until the end
4 1 4 4 3 4 2 3 9 1 1 restart and stop at 1
8 4 5 1 2 3 4 3 3 4 4 2
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 restart and stop at 2
Em seguida, preenchemos os últimos espaços com os dígitos restantes.
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 7 2 4 9
2 4 6 6 7 4 5 8 0 1 2 2 4
5 1 4 1 1 5 4 2 2 4 6 7 9
2 7 2 9 2 2 9 6 1 3 1 1 4
4 0 1 0 8 2 9 1 8 1 4 1 4
4 1 4 4 3 4 2 3 9 1 1 9 4
8 4 5 1 2 3 4 3 3 4 4 2 3
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 5 6 8
Agora, lemos as colunas exatamente da mesma maneira que fizemos na primeira transposição.
71431148 42711925 861904185 22614147 45499243 28261334 80218938
641701404 025244820 645224398 271283226 94944438 064214521
E divida tudo em grupos de 5 dígitos:
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521
5. Finalize a mensagem
A etapa final é inserir nosso identificador de mensagem aleatória,, 47921
na própria mensagem. O dígito final da data fixada 6
indica a distância que o grupo deve estar do final.
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521
Notas para este desafio
- Você recebe um mínimo de cinco entradas: a mensagem, a palavra-chave da letra, a frase-chave, a data e um número pessoal. Você pode incluir duas entradas adicionais: o identificador de mensagem aleatória e os nulos necessários para preencher a mensagem ou sua função pode gerar alguns números aleatórios por si só.
- Você pode assumir que todas as entradas são válidas, com o número correto de dígitos e letras (identificador de mensagem de 5 dígitos, pelo menos 20 dígitos para a frase-chave e assim por diante). Você pode presumir que suas strings (a mensagem e as palavras-chave) já tiveram toda a pontuação e os espaços removidos, exceto aqueles que você permite na sua versão e que os números já estão demarcados com sinais numéricos.
- A primeira palavra-chave não deve conter letras duplicadas e, no seu código, você pode supor que nunca tenha letras duplicadas.
- O idioma que você usa para codificar não importa, desde que o idioma esteja preexistente, o alfabeto esteja preexistente e você especifique o idioma que usará na sua resposta.
- Qualquer que seja o alfabeto que você emprega para o seu tabuleiro de damas, você pode adicionar ou remover símbolos para preencher o tabuleiro de damas. Especifique para que você usa esses símbolos (por exemplo, pontuação, um símbolo "início da mensagem" separado, símbolos para palavras comuns). Você pode renunciar inteiramente ao sinal numérico e soletrar os números ou incluir cada dígito no tabuleiro de damas, usando o slot onde o sinal numérico era para outra coisa. Especifique qual tabuleiro de damas você usou em sua resposta.
- A saída deve ser uma sequência de grupos de cinco dígitos separados por espaço, uma lista de números inteiros de cinco dígitos ou algo semelhante.
- Eu usei a indexação zero e
0123456789
no meu exemplo. Você pode usar a indexação 1 e1234567890
, ou algum outro sistema em sua resposta, desde que especifique o que usou.
Aqui está um exemplo de implementação no Ideone .
Este é um post longo e eu escrevi a maioria manualmente, portanto, se houver partes confusas neste post ou erros na minha contagem e transposição, informe-me. Boa sorte e bom golfe!
fonte
adding the first two digits without adding
Você quer dizer carregar?without borrowing
ewithout carrying
? Você quer dizer adicionar e subtrair mod10
, ie(6+7) mod 10 = 3
e(6-8) mod 10 = 8
?Respostas:
Python 3 ,
14231348132413161300128612501249120912061204 bytesEsse é definitivamente o golfe mais longo que já fiz e o único golfe em que fiquei seriamente preocupado com a falta de nomes de variáveis de um caractere. Sugestões de golfe são bem-vindas. Experimente online!
Estou codificando com o alfabeto latino maiúsculo com caracteres adicionais
.
e#
, usando a indexação 0 e0123456789
ao converterg
parat
. Meu tabuleiro de damas está em um formato semelhante ao seguinte exemplo:Edit: -63 bytes, graças à sugestão do TuukkaX de reduzir algumas das funções usadas com freqüência com variáveis de uma letra. -12 bytes de tornar
a, g, t
mais compacto.Edit: -24 bytes de criação removendo nomes de variáveis para chaves intermediárias que são usadas apenas uma vez, a saber
a, g, s, S, k, K
.Editar: -74 bytes da consolidação
H(), T() and C()
.Edit: -1 byte, graças a Nick A pela sugestão de mudar
ord(s[i])+ord(s[i+1])
parasum(map(ord,s[i:i+2]))
. -2 bytes da alteração de 2+=[a]
chamadas para+=a,
. -13 bytes de alterar comoG()
encontrou o índice do mínimo des
. -2 bytes da mudançay=(y+1)%v
paray=-~y%v
. -15 bytes da atribuiçãok.index()
aK
. -4 bytes da atribuição10
aW
. -5 bytes da atribuição1-I(d[-1])
aoX
interiorV
. -3 bytes doC()
loop principal da reescrita . -2 bytes de reorganizaçãoT()
.Ungolfing:
fonte
ord(seq[i])+ord(seq[i+1])
parasum(map(ord,seq[i:i+2]))
salva 1 caractere, acredito.C,
288027692766276227432741273926992458 bytesMeu Deus. Este é o programa mais longo que já tive para jogar golfe. Este também é o primeiro no qual, na verdade, fiquei sem nomes de variáveis de um caractere para o escopo global e, portanto, tive que passar a usar alguns de dois caracteres (o fato de aparentemente não poder redefinir variáveis não ajuda). Dicas de golfe são, portanto, muito apreciadas.
Ungolfed
Compila sem nenhum aviso, ao contrário da versão em golfe. Pequenas alterações feitas na versão golfed não serão refletidas nesta versão ungolfed.
Notas
Isso usa um tabuleiro de damas semelhante ao seguinte para codificar a mensagem:
Isso pressupõe que todas as strings aplicáveis são fornecidas em maiúsculas. A mensagem também deve ter toda a pontuação, exceto os períodos removidos e todos os números demarcados por
#
s, enquanto a frase-chave deve ter toda a pontuação removida.A mensagem codificada resultante é enviada para STDOUT como uma sequência de grupos de cinco dígitos separados por espaço.
A mensagem de entrada deve estar em inglês.
Eu teria combinado algumas das funções que usei, mas teria que recorrer ao uso de mais nomes de variáveis de duas letras, tornando o programa final mais longo do que seria com mais algumas funções.
Atualmente, isso não pressupõe que a palavra-chave (pelo menos em inglês) sempre contenha o mesmo conjunto de letras e, portanto, compensa isso removendo duplicatas, manipulando o tabuleiro de damas etc. Esse recurso aparentemente não é exigido pelo OP, então, atualmente, estou jogando fora os bytes extras desnecessários que estão ocupando.Atualizado para a versão golfada.fonte
JavaScript (ES6),
946938953 bytesVi no final de semana que ainda não havia uma entrada de JS para isso, então aqui está a minha (última hora) tentativa. Implementar e jogar golfe era tão louco quanto divertido!
Snippet de demonstração
Mostrar snippet de código
Editar: -8 bytes
Percebeu que havia parênteses extras em torno da função
S,J,A,Q
Editar: +15 bytes
Atualizada a lógica de como a
message id
mensagem é colocada na mensagem final (agora 1 indexada e 0 não a inclui na saída).Ungolfed
Notas
Isso usa um tabuleiro de damas semelhante ao seguinte para codificar a mensagem:
Todas as strings são fornecidas em maiúsculas. A mensagem é latina alfanumérica (mais
.
e#
) e deve ter toda a pontuação (exceto pontos) removida. Todos os números já devem estar marcados com#
s. A frase-chave deve ter todos os espaços / pontuação removidos.A mensagem resultante é retornada como uma matriz de sequências de 5 dígitos.
Aprimoramentos
Sinto que há uma maneira de abusar do "Todos os idiomas" para salvar alguns bytes. Se eu tivesse mais tempo, refiguraria isso para assumir que o idioma era algo como o havaiano, com apenas 12 letras.
Todas as sugestões de golfe são sempre bem-vindas.
fonte
message identifier
parece estar7
longe do final, em vez de6
. Além disso, na sua versão não-gasta, o mesmoId
parece estar6
longe do começo, e não do fim.1
significa o final, onde você diria que o jogomessage identifier
deveria continuar0
? Eu posso mudar isso, só preciso saber.0
omessage identifier
deve ser omitido da saída.Clojure,
11971212 bytesEstou exausta.
Atualização: adicionada a localização de divisão aleatória necessária da mensagem, a versão não-gasta usa a mesma localização do exemplo fornecido, para que o algoritmo possa ser facilmente verificado.
Entradas de amostra e caso de teste:
Ungolfed:
Possui uma implementação alternativa no tabuleiro de damas
B
que é igual à definição da tarefa. Mas o envio usa outro em que os alfabetos não utilizados preenchem primeiro a 2ª linha e depois a 3ª vez, em vez de preencher coluna por coluna.fonte
coords
é gerado duas vezes, primeiro gerando a forma triangular e depois preenchendo as coordenadas que estavam faltando. Também "preenchimento de comprimento de multiplicação de N" pode ter solução mais elegante que concatenando N - 1 e elementos de separação para comprimentos de N.(split-at 49 mymsg)
49, deve ser algo como(rand-int(count mymsg))
resposta correta seria um pouco mais de 1200 bytes. zzz