Cifra de Bacon: uma introdução à esteganografia

14

Este porquinho foi para o mercado, este porquinho escreveu algum código ...

Ah, espere, não estamos falando sobre esse bacon, estamos falando sobre Sir Francis Bacon! Especificamente, a cifra Bacon concebida no final dos anos 1500 , como um método de ocultar uma mensagem dentro de outra mensagem, um método de esteganografia .

A cifra funciona ocultando a mensagem na apresentação do texto, em vez de seu conteúdo. Primeiro, as letras da sua mensagem são codificadas em binário (de 0 a 25) da seguinte maneira:

Nota: Por favor, use a seguinte codificação em seu código e não se preocupe com números, espaços ou outros símbolos na entrada, embora eu possa conceber algum bônus para aqueles que incluem esses caracteres em sua codificação. Se você incluir outros símbolos, as letras ainda deverão ocupar os espaços de 0 a 25 na codificação.

Letter  Encoding
A       AAAAA
B       AAAAB
C       AAABA
D       AAABB
E       AABAA
F       AABAB
G       AABBA
H       AABBB
I       ABAAA
J       ABAAB
K       ABABA
L       ABABB
M       ABBAA
N       ABBAB
O       ABBBA
P       ABBBB
Q       BAAAA
R       BAAAB
S       BAABA
T       BAABB
U       BABAA
V       BABAB
W       BABBA
X       BABBB
Y       BBAAA
Z       BBAAB

Depois de codificar todas as letras da sua mensagem nos Aes e Bs acima, você deve agora selecionar dois tipos de letra para o seu código. Neste exemplo, usarei texto normal para o tipo de letra Ae texto em negrito para o tipo de letra B.

Então a mensagem

HELLOWORLD

está codificado para

AABBB AABAA ABABB ABABB ABBBA BABBA ABBBA BAAAB ABABB AAABB

E agora ocultamos esse binário com um texto de portadora .

A rápida raposa marrom pula sobre os cães preguiçosos, brincando nos campos onde os pastores vigiam.

Tudo bem se a mensagem da transportadora for maior que a mensagem codificada real, embora não possa ser mais curta. Agora, transformamos o texto da operadora em negrito, de acordo com o local Bna mensagem codificada,

Th e qu ic k bro w n fo x j u pf s ove r t h e l az y do g s , gam b o l i ng em t ele campos onde os pastores mantém relógio.

Que sem Markdown lê como

Th**e** **qu**ic**k** bro**w**n **fo**x **j**u**mp**s **ove**r **t**h**e** **l**az**y** 
**do**g**s**, gam**b**o**l**i**ng** in t**he** fields where the shepherds keeps watch.

Observe que eu não usei a pontuação na mensagem da operadora para codificar a mensagem, mas se a pontuação é codificada ou não, é com você /.

Regras

  • Sua entrada será a mensagem a ser codificada e uma mensagem da operadora. Se a mensagem da transportadora for muito curta, retorne algum tipo de mensagem de erro.

  • Você deve selecionar dois tipos de letras para codificar Ae B, como letras maiúsculas, minúsculas, itálico , negrito , itálico , tachado , in code formate assim por diante. Você deve usar a forma de Markdown do Stack Exchange para codificar esses tipos de letra, ou seja,

    UPPERCASE, lowercase, *italic*, **bold**, 
    ***bold italic***, <s>strikethrough</s>, `in code format`
    
  • Sua saída deve ser sua mensagem da operadora agora codificada, mostrada com Markdown ou mostrada sem, como visto no exemplo acima.

  • Você só precisa criar um algoritmo de codificação. Quaisquer algoritmos de decodificação que você deseja fornecer são bem-vindos, mas no momento da redação deste documento não ajudará nem prejudicará sua pontuação.

  • Seu código deve ser um programa ou uma função.

  • Esse é o código golf, portanto o menor número de bytes vence.

Como sempre, se o problema não estiver claro, entre em contato. Boa sorte e bom golfe!

Sherlock9
fonte
3
Então, realmente não há razão para não usar maiúsculas / minúsculas, já que todo o resto custa mais bytes
Mego
6
Eu acho que há um erro de digitação em "não estamos falando sobre esse bacon", porque certamente você estava falando sobre Kevin Bacon, então o "b" deve ser maiúsculo, certo?
Martin Ender

Respostas:

1

Pitão, 47 bytes

Vsm.[05jxGd2r~zw0#I}Jr@z~Z+1Z0GBpJ)p?NrJ1J;>zZ

Experimente aqui .

Explicação:

             ~zw                               - Get the first line of input and 
                                               - set z to the next line
            r   0                              - Turn it to lower case
  m                                            - Map each character
        xGd                                    - Get it's position in the alphabet
       j   2                                   - Turn it to base 2
   .[05                                        - Pad the start with 0's
 s                                             - Turn it to a 1d-array (flatten it)
V                                        ;     - For N in above array:
                 #                )            - While 1:
                      @z~Z+1Z                  - Get the current position in the 
                                               - second line and increment the position
                    Jr       0                 - Set J to it lowercased
                  I}          GB               - If it's a letter, break
                                pJ             - Otherwise, print it
                                    ?N         - Is the character code
                                               - (the current 1d-array) 1
                                      rJ1      - Get the current char uppered
                                         J     - Leave it lowered
                                   p           - Print the character
                                           >zZ - Print out the rest of the second input
Azul
fonte
1

Python 3, 216 211 231 225 207 bytes

Esta é uma solução que usa texto normal e itálico no estilo Markdown para seus dois tipos de letra. E codifica tudo na mensagem da operadora, exceto os espaços.

Editar: teve que corrigir o código para que o resultado fosse impresso corretamente e adicionou exemplos abaixo do código.

Editar: Editou o código para uma solução em maiúscula / minúscula anteriormente pior, devido a problemas na impressão do itálico corretamente.

def g(s,c):
 c=c.lower();w=[h.upper()for h in s if h.isalpha()];t=''.join("{:05b}".format(ord(i)-65)for i in w);r='';j=m=0
 while t[j:]:a=c[m];x=a!=" ";r+=[a,a.upper()][x*int(t[j])];j+=x;m+=1
 return r+c[m:]

Exemplos

>>> g('HELLOWORLD', 'The quick brown fox jumps over the lazy dogs, gamboling in the fields 
where the shepherds keep watch')
'thE QUicK broWn FOx JuMPs OVEr ThE LazY DOgS, gaMbOlINg in THe fields where the shepherds keep watch'

Ungolfed:

def bacon(message, carrier):
    # Lowers the case of the carrier message
    carrier = carrier.lower()
    # Removing all non-alphabetic characters and making the rest uppercase
    words = ""
    for char in message:
        if char.isalpha():
            words += char.upper()
    # Encoding the message
    binary = ""
    for letter in words:
        encode = ord(letter) - 65
        binary += "{:05b}".format(encode)
    # Encoding the carrier message
    result = ""
    bin_index = 0
    char_index = 0
    while bin_index < len(binary):
        letter = carrier[char_index]
        # If letter isn't a space and it needs to be encoded
        if letter != " " and int(binary[bin_index]): 
            letter = letter.upper()
        result += type + letter + type
        # The encoding only proceeds if letter wasn't a space
        bin_index += letter != " "
        # char_index increments whether or not letter was alphabetical
        char_index += 1
    # Return the encoded text and any leftover characters from the carrier message
    return result + carrier[char_index : ]
Sherlock9
fonte
0

C, 124 bytes

Isso requer que os argumentos estejam em uma codificação compatível com ASCII (por exemplo, ISO-8859.1 ou UTF-8). Ele modifica a transportadora no local e retorna 0 em caso de sucesso ou diferente de zero. A codificação é A== minúscula e B== maiúscula. As letras de transporte não utilizadas são definidas como superiores.

int f(char*p,char*s){int m=16;do{if(isalpha(*s)){*s|=32;*s-=(*p-1)&m?32:0;if(!(m/=2)){m=16;p+=!!*p;}}}while(*++s);return*p;}

Explicação

Incluindo um programa de teste. Passe as letras para codificar como o primeiro argumento e a string portadora como o segundo.

#include <stdio.h>
#include <ctype.h>

/* ASCII or compatible encoding assumed */
int f(char *p, char *s)         /* plaintext, carrier */
{
    int m=16;                   /* mask */
    do {
        if (isalpha(*s)) {
            *s |= 32;
            *s -= (*p-1)&m ? 32 : 0;
            if (!(m/=2)) {
                /* reset mask and advance unless we reached the end */
                m=16;
                p+=!!*p;
            }
        }
    } while (*++s);

    /* 0 (success) if we finished p, else non-zero */
    return *p;
}

int main(int argc, char **argv)
{
    int r = argc < 3 || f(argv[1], argv[2]);
    if (r)
        puts("~!^%&$+++NO CARRIER+++");
    else
        puts(argv[2]);
    return r;
}

Saída de teste:

$ ./66019 "HELLOWORLD" "The quick brown fox jumps over the lazy dogs, gamboling in the fields where the shepherds keep watch."  
thE QUicK broWn FOx JuMPs OVEr ThE LazY DOgS, gamBoLiNG in tHE FIELDS WHERE THE SHEPHERDS KEEP WATCH.
Toby Speight
fonte