Doppelbuchstaben-Steganographie

19

Steganography verbirgt eine bestimmte Nachricht in einem bestimmten Träger und erzeugt ein Paket, das nicht verdächtig aussieht. Für diese Herausforderung schreiben Sie ein Programm, das eine ASCII-Nachricht und einen ASCII-Träger als Eingabe verwendet, und geben oder drucken ein Paket, das mit dem Träger identisch ist, mit der Ausnahme, dass die Zeichen, die der Nachricht entsprechen, in derselben Reihenfolge verdoppelt werden, in der sie angezeigt werden die Nachricht.

Regeln:

  1. Wenn der Träger bereits mehrmals Sequenzen desselben Zeichens enthält und diese nicht zum Codieren eines Zeichens der Nachricht verwendet werden, werden sie vom Programm auf ein einzelnes Zeichen reduziert.
  2. Wenn der Spediteur die Nachrichtenzeichen nicht in der richtigen Reihenfolge enthält, gibt das Programm möglicherweise nichts, den Spediteur selbst oder einen Fehler zurück.
  3. Sie können davon ausgehen, dass die Nachricht und der Träger nicht leere ASCII-Zeichenfolgen sind.
  4. Auf die Groß- und Kleinschreibung kommt es an: A ist nicht gleichbedeutend mit a.
  5. Wenn mehr als ein Paket gültig ist, kann Ihr Programm eines oder alle davon ausgeben.
  6. Das Leerzeichen ist ein Zeichen wie jedes andere Zeichen.

Testfälle:

Paket für den Nachrichtenträger
"hi" "ist es angekommen?" "Ist es angekommen?" ODER "ist es angekommen?"
"Herr" "ist es angekommen?" "Ist es angekommen?"
"foo" "ist es angekommen?" "" ODER "ist es angekommen?" ODER ein Fehler.
"Auto" "Katzen sind cool." "CCaats arre col."
"Auto" "Katzen sind cool." "" ODER "Katzen sind cool." ODER ein Fehler.
"Couch" "Couch" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Dies ist Codegolf, so dass nur wenige Bytes gewinnen.

jkpate
quelle
5
Überhaupt
Ist "oooo oa"(mit 2 Leerzeichen) eine gültige Ausgabe für den letzten Testfall?
Arnauld
3
Es ist keine gültige Ausgabe, da die Reihenfolge der doppelten Zeichen im Paket mit der Reihenfolge der Zeichen in der Nachricht übereinstimmen muss. In der Nachricht haben wir ein 'o', dann ein '', dann ein 'o', aber Ihr Paket hat das Leerzeichen nach dem 'o'
jkpate
Ah ja, das macht Sinn.
Arnauld
1
Nein. Mein Grund für diese Regel ist, dass die Ausgabe des Programms im Falle einer Nichtlösung eindeutig sein sollte, dass keine Lösung möglich ist. Die drei zulässigen Ausgaben sind eindeutig, für den deduplizierten Fall wäre jedoch eine umfassendere Überprüfung erforderlich.
jkpate

Antworten:

5

Gelee , 28 Bytes

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

Ein volles Programm Mitnahmen carrierund messageals Kommandozeilen - Argumente , die das Ergebnis druckt
(für ein nicht packbares gibt es messagedas unveränderte aus carrier).

Probieren Sie es online!Oder sehen Sie sich die Testsuite an .

Wie?

ẹⱮŒ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')
Jonathan Allan
quelle
3

JavaScript (ES6), 71 Byte

Übernimmt die Eingabe als (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

Probieren Sie es online!


Alternative Version, 66 Bytes

Wenn wir die Nachricht als ein Array von Zeichen annehmen können:

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

Probieren Sie es online!


Bearbeiten : Vielen Dank an @tsh, dass ich vergessen habe, Code zu entfernen, wenn ich von einer nicht rekursiven auf eine rekursive Version umgestiegen bin.

Arnauld
quelle
Sie könnten entfernen, p=da p von einem Parameter übergeben wird.
tsh
@tsh Ups. Es ist ein Restcode aus den vorherigen, nicht rekursiven Versionen, den ich vergessen habe, zu entfernen. Vielen Dank!
Arnauld
2

Haskell, 124 121 107 101 97 95 90 Bytes

(#).(++"ü")
"ü"#[]=[]
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

Löst die Ausnahme "Nicht erschöpfende Muster" aus, wenn der Netzbetreiber die Nachricht nicht enthält.

Probieren Sie es online!

Edit: -5 Bytes dank @Laikoni.

nimi
quelle
Ich denke, das Wechseln der Fälle ermöglicht Ihnen das Löschen m==c: Probieren Sie es online aus!
Laikoni
1

Retina 0.8.2 , 67 Bytes

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

Probieren Sie es online!Nimmt den Träger in die erste Zeile und die Nachricht in die zweite Zeile. Erläuterung:

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

Prozessläufe mit 1 oder mehr identischen Zeichen des Trägers. Wenn die Nachricht auch einen Durchlauf von mindestens einem Zeichen enthält, hängen Sie den kürzeren der beiden Durchläufe doppelt an die Ausgabe an, andernfalls hängen Sie ein einzelnes Zeichen des Trägers an die Ausgabe an. Jeder Lauf von Ausgabezeichen wird mit einem Zeilenumbruch abgeschlossen, um es von der Eingabe zu unterscheiden. Das (?!¶)am Ende verhindert, dass der Regex denkt, dass der Träger die Nachricht ist, sobald die Nachricht erschöpft ist, wie es normalerweise $erlaubt ist, zu passen, wo ¶$es passen würde.

M!s`.*¶$

Löschen Sie alles, wenn die Nachricht nicht vollständig verschlüsselt ist.

Entfernen Sie die Zeilenumbrüche aus der Ausgabe.

Neil
quelle
Ich denke, dass es den vorletzten Testfall nicht besteht (was ich, um fair zu sein, im ersten Beitrag nicht hatte).
jkpate
@jkpate Danke für den Hinweis; Ich musste meine Herangehensweise leicht umschreiben.
Neil
0

Sauber , 118 Bytes

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]

Probieren Sie es online!

Nimmt zuerst den Träger, dann die Nachricht.

Fehler mit, Run time error, rule '$;2' in module 'main' does not matchwenn die Nachricht nicht passt.

Οurous
quelle
0

Ruby , 73 Bytes

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

Probieren Sie es online!

Rekursive Funktion, nimmt Eingaben als Array von Zeichen an.

Ich hatte ausnahmsweise gehofft, die in Ruby integrierte squeezeMethode zu verwenden, mit der aufeinanderfolgende Läufe desselben Zeichens an eine einzige Instanz vergeben werden. Aber leider, nein - die letzten beiden Testfälle haben alles so sehr durcheinander gebracht, dass ich auf einen völlig anderen Ansatz zurückgreifen musste, und dies stellte sich im Grunde als eine Antwort von Arnauld heraus .

Kirill L.
quelle
0

Powershell, 134 Bytes

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)

Das Skript gibt das zurück empty string wenn der Träger die Nachrichtenzeichen nicht in der richtigen Reihenfolge enthält.

Weniger Golf-Testskript:

$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"
}

Ausgabe:

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
mazzy
quelle
0

C (gcc) , 69 + 12 = 81 Bytes

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

Übersetzen mit (12 Bytes)

-Dp=putchar(

Probieren Sie es 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
}
attinat
quelle