La cifra di Bacon: un'introduzione alla steganografia


14

Questo porcellino è andato sul mercato, questo porcellino ha scritto del codice ...

Ah aspetta, non stiamo parlando di quella pancetta, stiamo parlando di Sir Francis Bacon! In particolare, la cifra Bacon ideata alla fine del 1500 , come metodo per nascondere un messaggio all'interno di un altro messaggio, un metodo di steganografia .

La cifra funziona nascondendo il messaggio nella presentazione del testo, piuttosto che nel suo contenuto. Innanzitutto, le lettere del tuo messaggio sono codificate in binario (da 0 a 25) come segue:

Nota: utilizzare la seguente codifica nel codice e non preoccuparsi di numeri, spazi o altri simboli nell'input, anche se potrei escogitare qualche bonus per coloro che includono questi caratteri nella loro codifica. Se includi altri simboli, le lettere devono comunque occupare gli spazi da 0 a 25 nella codifica.

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

Dopo aver codificato tutte le lettere del tuo messaggio nelle As e Bs precedenti, ora devi selezionare due caratteri tipografici per il tuo codice. Per questo esempio, userò il testo normale per il carattere tipografico Ae il testo in grassetto per il carattere tipografico B.

Quindi il messaggio

HELLOWORLD

è codificato in

AABBB AABAA ABABB ABABB ABBBA BABBA ABBBA BAAAB ABABB AAABB

E ora nascondiamo questo file binario con un testo di supporto .

La rapida volpe marrone salta sui cani pigri, giocando d'azzardo nei campi dove i pastori vegliano.

Va bene se il messaggio del corriere è più lungo del messaggio effettivamente codificato, anche se non può essere più breve. Ora trasformiamo il testo del corriere in grassetto in base a dove si trovano le Bs nel messaggio codificato,

Th e qu ic k bro w n fo x j u mp s ove r t h e l az y fare g s , gam b o l i ng in t ha campi in cui i pastori mantiene orologio.

Che senza Markdown si legge come

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.

Nota che non ho usato la punteggiatura nel messaggio del corriere per codificare il messaggio, ma se la punteggiatura è codificata o meno dipende da te /.

Regole

  • Il tuo input sarà il messaggio da codificare e un messaggio di operatore. Se il messaggio del corriere è troppo breve, restituisce una sorta di messaggio di errore.

  • È necessario selezionare due tipi di carattere per la codifica Ae B, come ad esempio lettere maiuscole, minuscole, corsivo , grassetto , corsivo grassetto , barrato , in code formate così via. È necessario utilizzare la forma di Markdown di Stack Exchange per codificare questi caratteri tipografici, ad es

    UPPERCASE, lowercase, *italic*, **bold**, 
    ***bold italic***, <s>strikethrough</s>, `in code format`
    
  • L'output deve essere il messaggio del corriere ora codificato, mostrato con Markdown o mostrato senza, come mostrato nell'esempio sopra.

  • Ti viene richiesto solo di creare un algoritmo di codifica. Tutti gli algoritmi di decodifica che desideri fornire sono i benvenuti, ma al momento della stesura non aiuteranno o ostacoleranno il tuo punteggio.

  • Il tuo codice deve essere un programma o una funzione.

  • Questo è il codice golf, quindi vince il minor numero di byte.

Come sempre, se il problema non è chiaro, per favore fatemi sapere. Buona fortuna e buon golf!


3
Quindi davvero non c'è motivo di non usare maiuscole / minuscole, dal momento che tutto il resto costa più byte
Mego

6
Penso che ci sia un refuso in "non stiamo parlando di quella pancetta", perché sicuramente stavi parlando di Kevin Bacon, quindi la "b" dovrebbe essere maiuscola, giusto?
Martin Ender,

Risposte:


1

Pyth, 47 byte

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

Provalo qui .

Spiegazione:

             ~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

1

Python 3, 216 211 231 225 207 byte

Questa è una soluzione che utilizza testo normale e corsivo in stile Markdown per i suoi due caratteri tipografici. E codifica tutto nel messaggio del gestore tranne gli spazi.

Modifica: ho dovuto correggere il codice in modo che il risultato venisse stampato correttamente e aggiunto esempi sotto il codice.

Modifica: modificato il codice con una soluzione maiuscola / minuscola precedentemente peggiore, a causa di problemi nella stampa corretta del corsivo.

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

Esempi

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

0

C, 124 byte

Ciò richiede che gli argomenti siano in una codifica compatibile ASCII (ad es. ISO-8859.1 o UTF-8). Modifica il corriere sul posto e restituisce 0 in caso di successo, altrimenti diverso da zero. La codifica è A== minuscole e B== maiuscole. Le lettere del corriere non utilizzate sono impostate in alto.

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

Spiegazione

Compreso un programma di test. Passa le lettere da codificare come primo argomento e la stringa del vettore come secondo.

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

Uscita di prova:

$ ./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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.