Steganografia z podwójnymi literami


19

Steganografia ukrywa daną wiadomość wewnątrz danego przewoźnika, tworząc pakiet, który nie wygląda podejrzanie. W tym wyzwaniu napiszesz program, który pobiera komunikat ASCII i nośnik ASCII jako dane wejściowe, i zwraca lub drukuje pakiet identyczny z nośnikiem, z wyjątkiem tego, że znaki odpowiadające wiadomości są podwojone, w tej samej kolejności, w jakiej występują wiadomość.

Zasady:

  1. Jeśli nośnik zawiera już sekwencje tego samego znaku więcej niż jeden raz i nie są one używane do kodowania znaku wiadomości, program zredukuje je do jednego znaku.
  2. Jeśli operator nie zawiera znaków komunikatu we właściwej kolejności, program może nie zwrócić niczego, samego przewoźnika lub błędu.
  3. Możesz założyć, że komunikat i nośnik nie są pustymi łańcuchami ASCII.
  4. Kapitalizacja ma znaczenie: A nie jest równoważne z.
  5. Gdy więcej niż jeden pakiet jest ważny, twój program może wypisać jeden lub wszystkie z nich.
  6. Space to postać jak każda inna postać.

Przypadki testowe:

Pakiet operatora wiadomości
„cześć”, czy to dotarło? ” „czy to się udało?” LUB „czy to się udało?”
„sir” „czy to dotarło?” „czy iit przybył?”
„foo” „czy dotarło?” „LUB” czy dotarło? ” LUB błąd.
„Samochód” „Koty są fajne”. „CCaats arre col.”
„samochód” „Koty są fajne”. „” LUB „Koty są fajne”. LUB błąd.
„Kanapa” „Kanapa” „CCoouucchh”
„oo” „oooooooooo” „oooo”
„o o” „oooo oooa” „oo ooa”

To jest kod golfowy, więc wygrywa najmniej bajtów.


5
Wcale nie podejrzane ...: P
Quintec

Czy "oooo oa"(z 2 spacjami) jest prawidłowym wyjściem dla ostatniego przypadku testowego?
Arnauld,

3
Nie jest to prawidłowy wynik, ponieważ kolejność podwójnych znaków w pakiecie musi być zgodna z kolejnością znaków w komunikacie. W wiadomości mamy „o”, potem „”, a następnie „o”, ale twoja paczka ma miejsce po o
jkpate

Ach tak, to ma sens.
Arnauld

1
Nie. Moje uzasadnienie tej reguły jest takie, że wyjście programu w przypadku braku rozwiązania powinno być jednoznaczne, że żadne rozwiązanie nie jest możliwe. Trzy dozwolone dane wyjściowe są jednoznaczne, ale w przypadku deduplikacji wymagane byłoby bardziej szczegółowe sprawdzenie.
jkpate

Odpowiedzi:


5

Galaretka , 28 bajtów

ẹⱮŒp<ƝẠ$ƇṪ
nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç?

Pełną podejmowanie programu carrieri messagejako argumenty wiersza poleceń, które drukuje wynik
(dla nie-packable messagewydruków niezmienionych carrier).

Wypróbuj online! Lub zobacz zestaw testowy .

W jaki sposób?

ẹⱮŒp<ƝẠ$ƇṪ - Link 1, helper function to find the indices to double: carrier, message
           -                               e.g. "programming", "rom"
 Ɱ         - map across message with:
ẹ          -   indices of                       [[2,5], [3], [7,8]]
  Œp       - Cartesian product                  [[2,3,7],[2,3,8],[5,3,7],[5,3,8]]
        Ƈ  - filter keep if:
       $   -   last two links as a monad:
     Ɲ     -     for neighbours:
    <      -       less than?                    [1,1]   [1,1]   [0,1]   [0,1]
      Ạ    -     all truthy?                     1       1       0       0
           -                                    [[2,3,7],[2,3,8]]
         Ṫ - tail (if empty yields 0)                    [2,3,8]

nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç? - Main Link: carrier, message
                ? - if...
               ç  - ...condition: last Link (the helper function) as a dyad
             ð    - ...then: perform the dyadic chain to the left (described below)
              ¹   - ...else: do nothing (yields carrier)
                  - (the then clause:)
 Ɲ                - for neighbours in the carrier
n                 - not equal?
     ¥            - last two links as a dyad:
   ç              -   call last Link (the helper function) as a dyad
    Ṭ             -   untruth (e.g. [2,5] -> [0,1,0,0,1])
  +               - add (vectorises)
      a⁸          - logical AND with carrier
        ḟ0        - filter out zeros
            ¦     - sparse application...
           ç      - ...to indices: call last Link (the helper function) as a dyad
          Ḥ       - ...do: double (e.g. 'x' -> 'xx')

3

JavaScript (ES6), 71 bajtów

Pobiera dane wejściowe jako (message)(carrier).

s=>g=([c,...C],p)=>c?(c==s[0]?(s=s.slice(1),c)+c:p==c?'':c)+g(C,c):s&&X

Wypróbuj online!


Alternatywna wersja, 66 bajtów

Jeśli możemy przyjąć wiadomość jako tablicę znaków:

s=>g=([c,...C],p)=>c?(c==s[0]?s.shift()+c:p==c?'':c)+g(C,c):s+s&&X

Wypróbuj online!


Edycja : Podziękowania dla @tsh za zauważenie, że zapomniałem usunąć trochę kodu przy przechodzeniu z wersji nierekurencyjnych na rekurencyjne.


Możesz usunąć, p=ponieważ parametr p jest przekazywany przez parametr.
tsh

@tsh Ups. To trochę resztkowego kodu z poprzednich, nierekurencyjnych wersji, o których zapomniałem usunąć. Dziękuję Ci!
Arnauld,

2

Haskell, 124 121 107 101 97 95 90 bajtów

(#).(++"ü")
"ü"#[]=[]
p@(m:n)#e@(c:d)|m/=c=c:p#snd(span(==c)d)|m==n!!0=m:m:n#d|1<2=m:n#e

Podnosi wyjątek „Niewyczerpujące wzorce”, jeśli przewoźnik nie zawiera komunikatu.

Wypróbuj online!

Edycja: -5 bajtów dzięki @Laikoni.


Myślę, że zmiana skrzynek pozwala upuścić m==c: Wypróbuj online!
Laikoni,

1

Retina 0.8.2 , 67 bajtów

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6
M!s`.*¶$
¶

Wypróbuj online! Przenosi operatora do pierwszego wiersza, a komunikat do drugiego wiersza. Wyjaśnienie:

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6

Przetwarza przebiegi 1 lub więcej identycznych znaków przewoźnika. Jeśli wiadomość zawiera również ciąg 1 lub więcej takich samych znaków, następnie dołącz krótszy z dwóch przebiegów do wyjścia w dwóch egzemplarzach, w przeciwnym razie dołącz do wyjścia jeden znak nośnika. Każdy ciąg znaków wyjściowych jest zakończony znakiem nowej linii, aby odróżnić go od danych wejściowych. Na (?!¶)końcu zapobiega wyrażeniu regularnemu, że przewoźnik jest wiadomością po wyczerpaniu wiadomości, ponieważ zwykle $dozwolone jest dopasowanie tam ¶$, gdzie pasowałoby.

M!s`.*¶$

Usuń wszystko, jeśli wiadomość nie została całkowicie zakodowana.

Usuń znaki nowej linii z wyniku.


Myślę, że nie przechodzi od drugiego do ostatniego przypadku testowego (czego, szczerze mówiąc, nie miałem w początkowej wiadomości).
jkpate,

@jkpate Dziękujemy za zwrócenie na to uwagi; Musiałem nieco przepisać moje podejście.
Neil,

0

Czysty , 118 bajtów

import StdEnv,StdLib
$[][]=[]
$[u:v]b#(_,w)=span((==)u)v
|b%(0,0)==[u]=[u,u: $if(v%(0,0)<>b%(1,1))w v(tl b)]=[u: $w b]

Wypróbuj online!

Najpierw bierze przewoźnika, potem wiadomość.

Błędy w Run time error, rule '$;2' in module 'main' does not matchprzypadku, gdy wiadomość nie pasuje.


0

Rubinowy , 73 bajty

f=->m,c,b=p{x,*c=c;x ?(x==m[0]?x+m.shift: x==b ?'':x)+f[m,c,x]:m[0]?x:''}

Wypróbuj online!

Funkcja rekurencyjna, przyjmuje dane wejściowe jako tablicę znaków.

Raz miałem nadzieję skorzystać z wbudowanej squeezemetody Ruby, która kontraktuje kolejne przebiegi tej samej postaci w jednej instancji. Ale niestety, nie - ostatnie dwa przypadki testowe wszystko tak mocno spieprzyły, że musiałem zastosować zupełnie inne podejście, co okazało się być w zasadzie odpowiedzią Arnaulda .


0

PowerShell, 134 bajty

param($m,$c)$c-csplit"([$m])"|%{$i+=$o=$_-ceq$m[+$i]
if($o-or$_-cne"`0$h"[-1]){$h+=($_-replace'(.)(?=\1)')*($o+1)}}
$h*!($i-$m.Length)

Skrypt zwraca, empty stringjeśli operator nie zawiera znaków wiadomości we właściwej kolejności.

Skrypt testu mniej golfowego:

$f = {

param($message,$carrier)
$carrier-csplit"([$message])"|%{                # split by chars of the message, chars itself included ([])
    $offset=$_-ceq$message[+$i]                 # 0 or 1 if current substring is a current message char (case-sensitive equality)
    $i+=$offset                                 # move to next message char if need it
    if($offset-or$_-cne"`0$h"[-1]){             # condition to remove redundant doubles after message char: arrrived -> arrived, ooo -> oo, etc
                                                # `0 to avoid exception error if $h is empty
        $h+=($_-replace'(.)(?=\1)')*($offset+1) # accumulate a double message char or a single substring without inner doubles: arried -> arived, anna -> ana, etc
    }
}
$h*!($i-$message.Length)                        # repeat 0 or 1 times to return '' if the carrier does not contain the message characters in the right order

}

@(
    ,('hi'         ,'has it arrived?'    ,'hhas iit arived?', 'hhas it ariived?')
    ,('hi?'        ,'has it arrived?'    ,'hhas iit arived??', 'hhas it ariived??')
    ,('sir'        ,'has it arrived?'    ,'hass iit arrived?')
    ,('foo'        ,'has it arrived?'    ,'')
    ,('Car'        ,'Cats are cool.'     ,'CCaats arre col.')
    ,('car'        ,'Cats are cool.'     ,'')
    ,('Couch'      ,'Couch'              ,'CCoouucchh')
    ,('oo'         ,'oooooooooo'         ,'oooo')
    ,('o o'        ,'oooo oooa'          ,'oo  ooa')
    ,('er'         ,'error'              ,'eerorr', 'eerror')
    ,('a+b'        ,'anna+bob'           ,'aana++bbob')
) | % {
    $message,$carrier,$expected = $_
    $result = &$f $message $carrier
    "$($result-in$expected): $result"
}

Wynik:

True: hhas iit arived?
True: hhas iit arived??
True: hass iit arrived?
True:
True: CCaats arre col.
True:
True: CCoouucchh
True: oooo
True: oo  ooa
True: eerror
True: aana++bbob

0

C (gcc) , 69 + 12 = 81 bajtów

g(char*m,char*_){for(;*_;++_)*m-*_?_[-1]-*_&&p*_):p p*m++));*m&&0/0;}

Kompiluj z (12 bajtów)

-Dp=putchar(

Wypróbuj online!

g(char*m,char*_){
    for(;*_;++_)        //step through _
        *m-*_?          //check if character should be encoded
            _[-1]-*_&&  //no? skip duplicates
                p*_)    //    print non-duplicates
        :p p*m++));     //print encoded character twice
    *m&&0/0;            //if m is not fully encoded, exit via Floating point exception
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.