Шифр Бекона: вступ до стеганографії


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і так далі. Ви повинні використовувати форму Markdown 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 байт

Це рішення, яке використовує звичайний текст та курсив у стилі Маркдаун для двох його шрифтів. І він кодує все в повідомленні носія, крім пробілів.

Редагувати: довелося виправити код, щоб результат був надрукований правильно та додав приклади під кодом.

Редагувати: Відредагував код на попередньо гірший / нижній регістр через проблеми з правильним друком курсивом.

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'

Безголівки:

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.