El cifrado de tocino: una introducción a la esteganografía

14

Este cerdito salió al mercado, este cerdito escribió un código ...

Ah, espera, no estamos hablando de ese tocino, ¡estamos hablando de Sir Francis Bacon! Específicamente, el cifrado Bacon ideó a fines del siglo XVI , como un método para ocultar un mensaje dentro de otro mensaje, un método de esteganografía .

El cifrado funciona ocultando el mensaje en la presentación del texto, en lugar de su contenido. Primero, las letras de su mensaje se codifican en binario (de 0 a 25) de la siguiente manera:

Nota: Utilice la siguiente codificación en su código y no se preocupe por los números, espacios u otros símbolos en la entrada, aunque puedo idear alguna bonificación para aquellos que incluyen estos caracteres en su codificación. Si incluye otros símbolos, las letras aún deben ocupar espacios 0-25 en la codificación.

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

Después de haber codificado todas las letras en su mensaje en el As y Bs anterior, ahora debe seleccionar dos tipos de letra para su código. Para este ejemplo, usaré texto normal para la tipografía Ay texto en negrita para la tipografía B.

Entonces el mensaje

HELLOWORLD

está codificado para

AABBB AABAA ABABB ABABB ABBBA BABBA ABBBA BAAAB ABABB AAABB

Y ahora ocultamos este binario con un texto de portador .

El rápido zorro marrón salta sobre los perros perezosos, jugando en los campos donde los pastores vigilan.

Está bien si el mensaje del operador es más largo que el mensaje codificado real, aunque no puede ser más corto. Ahora convertimos el texto del operador en negrita de acuerdo con la Bubicación de los s en el mensaje codificado,

Th e qu ic k bro w n fo x j u mp s ove r t h e l az y hacer g s , gam b o l i ng en t él campos donde los pastores mantiene reloj.

Que sin Markdown se lee 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.

Tenga en cuenta que no utilicé la puntuación en el mensaje del operador para codificar el mensaje, pero si la puntuación está codificada o no depende de usted /.

Reglas

  • Su entrada será el mensaje que se codificará y un mensaje del operador. Si el mensaje del operador es demasiado corto, devuelva algún tipo de mensaje de error.

  • Debe seleccionar dos tipos de letra para codificar A y B, como MAYÚSCULAS, minúsculas, cursiva , negrita , negrita cursiva , tachado , in code formatetc. Debe usar la forma de Markdown de Stack Exchange para codificar estos tipos de letra, es decir

    UPPERCASE, lowercase, *italic*, **bold**, 
    ***bold italic***, <s>strikethrough</s>, `in code format`
    
  • Su salida debe ser su mensaje de operador ahora codificado, ya sea con Markdown o sin él, como se ve en el ejemplo anterior.

  • Solo se requiere que haga un algoritmo de codificación. Cualquier algoritmo de decodificación que desee proporcionar es bienvenido, pero al momento de escribir no ayudará ni dificultará su puntaje.

  • Su código debe ser un programa o una función.

  • Este es el código de golf, por lo que gana el menor número de bytes.

Como siempre, si el problema no está claro, hágamelo saber. ¡Buena suerte y buen golf!

Sherlock9
fuente
3
Así que realmente no hay razón para no usar mayúsculas / minúsculas, ya que todo lo demás cuesta más bytes
Mego
66
Creo que hay un error tipográfico en "no estamos hablando de ese tocino", porque seguramente estabas hablando de Kevin Bacon, por lo que la "b" debe estar en mayúscula, ¿verdad?
Martin Ender

Respuestas:

1

Pyth, 47 bytes

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

Pruébalo aquí .

Explicación:

             ~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
fuente
1

Pitón 3, 216 211 231 225 207 bytes

Esta es una solución que utiliza texto normal y cursivas de estilo Markdown para sus dos tipos de letra. Y codifica todo en el mensaje del operador excepto los espacios.

Editar: tuve que arreglar el código para que el resultado se imprima correctamente y agregue ejemplos debajo del código.

Editar: editó el código a una solución en mayúsculas / minúsculas peor anteriormente, debido a problemas al imprimir las cursivas correctamente.

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

Ejemplos

>>> 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'

Sin golf:

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
fuente
0

C, 124 bytes

Esto requiere que los argumentos estén en una codificación compatible con ASCII (por ejemplo, ISO-8859.1 o UTF-8). Modifica el operador en el lugar y devuelve 0 en caso de éxito, o no es cero de lo contrario. La codificación es A== minúsculas y B== mayúsculas. Las letras de portador no utilizadas se establecen en la parte superior

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

Explicación

Incluyendo un programa de prueba. Pase las letras para codificar como el primer argumento y la cadena de soporte como el 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;
}

Prueba de salida:

$ ./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
fuente