Chiffre de Bacon: une introduction à la stéganographie

14

Ce petit cochon est allé au marché, ce petit cochon a écrit du code ...

Ah attendez, nous ne parlons pas de ce bacon, nous parlons de Sir Francis Bacon! Plus précisément, le chiffrement Bacon conçu à la fin des années 1500 , comme une méthode pour cacher un message dans un autre message, une méthode de stéganographie .

Le chiffrement fonctionne en dissimulant le message dans la présentation du texte plutôt que dans son contenu. Tout d'abord, les lettres de votre message sont encodées en binaire (de 0 à 25) comme suit:

Remarque: veuillez utiliser l'encodage suivant dans votre code et ne vous souciez pas des nombres, des espaces ou d'autres symboles dans l'entrée, bien que je puisse concevoir un bonus pour ceux qui incluent ces caractères dans leur encodage. Si vous incluez d'autres symboles, les lettres doivent toujours occuper les espaces 0 à 25 dans l'encodage.

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

Après avoir encodé toutes les lettres de votre message dans les As et Bs ci-dessus, vous devez maintenant sélectionner deux polices de caractères pour votre code. Pour cet exemple, j'utiliserai du texte normal pour la police Aet du texte gras pour la police B.

Donc le message

HELLOWORLD

est codé en

AABBB AABAA ABABB ABABB ABBBA BABBA ABBBA BAAAB ABABB AAABB

Et maintenant, nous cachons ce binaire avec un texte porteur .

Le rapide renard brun saute par-dessus les chiens paresseux, gambadant dans les champs où les bergers veillent.

C'est correct si le message porteur est plus long que le message codé réel, bien qu'il ne puisse pas être plus court. Maintenant, nous transformons le texte du support en gras en fonction de l'emplacement des Bs dans le message codé,

Th e qu ic k bro w n fo x j u mp s ove r t h e l az y faire g s , gam b o l i ng dans t - il des domaines où les bergers maintient montre.

Qui sans Markdown se lit comme

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.

Notez que je n'ai pas utilisé la ponctuation dans le message porteur pour coder le message, mais que la ponctuation soit codée ou non, cela dépend de vous /.

Règles

  • Votre entrée sera le message à encoder et un message de porteur. Si le message de l'opérateur est trop court, renvoyez une sorte de message d'erreur.

  • Vous devez sélectionner deux polices de caractères pour le codage Aet B, comme majuscule, minuscule, italique , gras , italique gras , barré , in code formatetc. Vous devez utiliser la forme de Markdown de Stack Exchange pour coder ces polices, c.-à-d.

    UPPERCASE, lowercase, *italic*, **bold**, 
    ***bold italic***, <s>strikethrough</s>, `in code format`
    
  • Votre sortie doit être votre message de transporteur maintenant codé, soit affiché avec Markdown, soit affiché sans, comme le montre l'exemple ci-dessus.

  • Il vous suffit de créer un algorithme de codage. Tous les algorithmes de décodage que vous souhaitez fournir sont les bienvenus, mais au moment de la rédaction, cela n'aidera ni n'entravera votre score.

  • Votre code doit être un programme ou une fonction.

  • C'est le golf de code, donc le plus petit nombre d'octets gagne.

Comme toujours, si le problème n'est pas clair, faites-le moi savoir. Bonne chance et bon golf!

Sherlock9
la source
3
Il n'y a donc vraiment aucune raison de ne pas utiliser les majuscules / minuscules, car tout le reste coûte plus d'octets
Mego
6
Je pense qu'il y a une faute de frappe dans "nous ne parlons pas de ce bacon", parce que vous parliez sûrement de Kevin Bacon, donc le "b" devrait être en majuscule, non?
Martin Ender

Réponses:

1

Pyth, 47 octets

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

Essayez-le ici .

Explication:

             ~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
Bleu
la source
1

Python 3, 216 211 231 225 207 octets

Il s'agit d'une solution qui utilise du texte normal et des italiques de style Markdown pour ses deux polices de caractères. Et il encode tout dans le message du transporteur, sauf les espaces.

Éditer: J'ai dû corriger le code pour que le résultat s'imprime correctement et a ajouté des exemples sous le code.

Modifier: modification du code pour une solution en majuscules / minuscules précédemment pire, en raison de problèmes d'impression correcte de l'italique.

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

Exemples

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

Non 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
la source
0

C, 124 octets

Cela nécessite que les arguments soient dans un codage compatible ASCII (par exemple ISO-8859.1 ou UTF-8). Il modifie la porteuse en place et renvoie 0 en cas de succès, ou différent de zéro sinon. Le codage est A== minuscule et B== majuscule. Les lettres de support inutilisées sont définies en haut.

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

Explication

Y compris un programme de test. Passez les lettres à coder comme premier argument et la chaîne de support comme deuxième.

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

Sortie de test:

$ ./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
la source