Шифр Бэкона: введение в стеганографию


14

Этот маленький поросенок вышел на рынок, этот маленький поросенок написал код ...

Подожди, мы не говорим об этом беконе, мы говорим о сэре Фрэнсисе Бэконе! В частности, шифр Бэкона, разработанный в конце 1500-х годов , как метод сокрытия сообщения в другом сообщении, метод стеганографии .

Шифр работает, скрывая сообщение в представлении текста, а не его содержания. Сначала буквы вашего сообщения кодируются в двоичную форму (от 0 до 25) следующим образом:

Примечание. Пожалуйста, используйте следующую кодировку в своем коде и не беспокойтесь о числах, пробелах или других символах на входе, хотя я могу придумать какой-то бонус для тех, кто включает эти символы в свою кодировку. Если вы включите другие символы, буквы должны по-прежнему занимать пробелы 0-25 в кодировке.

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

Закодировав все буквы в вашем сообщении в As и Bs выше, вы должны теперь выбрать две гарнитуры для своего кода. В этом примере я буду использовать обычный текст для гарнитуры Aи жирный текст для гарнитурыB .

Итак, сообщение

HELLOWORLD

закодирован в

AABBB AABAA ABABB ABABB ABBBA BABBA ABBBA BAAAB ABABB AAABB

И теперь мы скрываем этот двоичный файл с текстом-носителем .

Быстрая коричневая лиса перепрыгивает через ленивых собак, играя в азартные игры на полях, где пастухи присматривают.

Это нормально, если сообщение-носитель длиннее, чем фактическое закодированное сообщение, хотя оно не может быть короче. Теперь мы превращаем текст-носитель в жирный в зависимости от того, гдеB в кодированном сообщении находятся буквы s,

Че е Qu IC к братан ш п FO х J ¯u тр ы Ов г т ч е л аз у делать г ы , гама б о л я нг в т он полей , где пастухи держат часы.

Который без уценки читается как

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.

Обратите внимание, что я не использовал пунктуацию в сообщении-носителе для кодирования сообщения, но независимо от того, закодирована ли эта пунктуация или нет, решать вам /.

правила

  • Ваш ввод будет сообщение, которое вы должны быть закодированы и сообщение перевозчика. Если сообщение оператора слишком короткое, верните какое-либо сообщение об ошибке.

  • Вы должны выбрать два шрифтами для кодирования Aи B, например, ВЕРХНИЙ, строчными буквами, курсивом , жирным шрифтом , выделены жирным курсивом , зачеркнутый , in code formatи так далее. Вы должны использовать форму разметки Stack Exchange для кодирования этих шрифтов, т.е.

    UPPERCASE, lowercase, *italic*, **bold**, 
    ***bold italic***, <s>strikethrough</s>, `in code format`
    
  • Ваш вывод должен быть вашим теперь закодированным сообщением-носителем, либо показанным с Markdown, либо показанным без, как видно из приведенного выше примера.

  • Вы только должны сделать алгоритм кодирования. Любые алгоритмы декодирования, которые вы хотите предоставить, приветствуются, но на момент написания статьи это не поможет и не помешает вашей оценке.

  • Ваш код должен быть программой или функцией.

  • Это код гольф, поэтому выигрывает наименьшее количество байтов.

Как всегда, если проблема неясна, пожалуйста, дайте мне знать. Удачи и хорошего гольфа!


3
Так что на самом деле нет причин не использовать верхний / нижний регистр, поскольку все остальное стоит больше байтов
Mego

6
Я думаю, что есть опечатка в «мы говорим не о том беконе», потому что вы наверняка говорили о Кевине Бэконе, поэтому букву «b» следует использовать с большой буквы, верно?
Мартин Эндер

Ответы:


1

Pyth, 47 байтов

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

Попробуй здесь .

Объяснение:

             ~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

Питон 3, 216 211 231 225 207 байт

Это решение, которое использует обычный текст и курсив в стиле Markdown для двух своих шрифтов. И это кодирует все в сообщении носителя, кроме пробелов.

Редактировать: пришлось исправить код, чтобы результат выводился правильно, и добавить примеры под кодом.

Редактировать: отредактировал код до ранее худшего варианта прописных / строчных букв из-за проблем с правильной печатью курсива.

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

Примеры

>>> 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 байта

Это требует, чтобы аргументы были в ASCII-совместимой кодировке (например, ISO-8859.1 или UTF-8). Он изменяет носитель на месте и возвращает 0 в случае успеха или ненулевое значение в противном случае. Кодировка: A== строчные и B== прописные. Неиспользованные буквы-носители устанавливаются на верхний.

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

объяснение

Включая тестовую программу. Передайте буквы для кодирования в качестве первого аргумента и строку-носитель в качестве второго.

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

Тестовый вывод:

$ ./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.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.